29、jQuery与Node.js开发指南

jQuery与Node.js开发指南

1 jQuery选择器与样式操作

在网页开发中,jQuery提供了强大的选择器和样式操作功能。通过选择器,我们可以精准地定位到需要操作的元素,再使用样式操作方法对元素进行样式修改。

1.1 奇偶选择器

:even :odd 选择器可以帮助我们选择偶数或奇数位置的元素。例如,要将每隔一个段落设置为红色,可以使用以下代码:

$('p:odd').css('color', 'red');

1.2 链式操作中的元素筛选

在jQuery链式操作中,我们可以使用 eq filter not find 来筛选匹配的元素。
- filter :将匹配的元素集合缩小到符合指定选择器的元素。例如:

$('p')
    .after('<hr>')
    .append('<sup>*</sup>')
    .filter(':odd')
    .css('color', 'red');
  • not :与 filter 相反,排除符合指定选择器的元素。例如:
$('p')
    .after('<hr>')
    .not('.highlight')
    .css('margin-left', '20px');
  • find :返回匹配给定查询的后代元素集合。例如:
$('p')
    .before('<hr>')
    .find('.code')
    .css('font-size', '30px');

1.3 展开jQuery对象

如果需要访问jQuery对象底层的DOM元素,可以使用 get 方法。示例如下:

// 获取第二个段落DOM元素
const para2 = $('p').get(1);
// 获取包含所有段落DOM元素的数组
const paras = $('p').get();

1.4 jQuery中的Ajax操作

jQuery提供了方便的方法来简化Ajax调用,如 ajax get post 。这些方法支持回调函数,同时也返回Promise对象,推荐使用Promise来处理服务器响应。以下是使用 get 方法重写的 refreshServerInfo 示例:

function refreshServerInfo() {
    const $serverInfo = $('.serverInfo');
    $.get('http://localhost:7070').then(
        // 成功返回
        function(data) {
            Object.keys(data).forEach(p => {
                $(`[data-replace="${p}"]`).text(data[p]);
            });
        },
        function(jqXHR, textStatus, err) {
            console.error(err);
            $serverInfo.addClass('error')
                .html('Error connecting to server.');
        }
    );
}

1.5 jQuery未来展望

虽然JavaScript和浏览器API不断改进,但jQuery仍然具有一定的实用性和相关性。目前jQuery的使用率仍然较高,对于有抱负的开发者来说,至少了解其基础知识是很有必要的。

2 Node.js基础与模块系统

2.1 Node.js简介

在2009年之前,JavaScript主要是一种浏览器脚本语言。2009年,Ryan Dahl创建了Node.js,使得JavaScript可以用于服务器端开发。Node.js的出现让JavaScript能够用于传统上由其他语言完成的任务,为开发者带来了很多便利。

2.2 Node.js基础

如果您会编写JavaScript,那么就可以编写Node.js应用程序。但需要注意的是,浏览器端的JavaScript使用的是特定于浏览器的API,而Node.js有自己独特的API,没有DOM等浏览器特有的对象。

2.3 Node.js模块系统

模块是一种封装和命名空间化代码的机制,可以避免命名冲突。以下是一个简单的模块示例:

// amanda.js
function calculate(a, x, n) {
    if(x === 1) return a*n;
    return a*(1 - Math.pow(x, n))/(1 - x);
}
module.exports = calculate;

// tyler.js
function calculate(r) {
    return 4/3*Math.PI*Math.pow(r, 3);
}
module.exports = calculate;

// app.js
const amanda_calculate = require('./amanda.js');
const tyler_calculate = require('./tyler.js');
console.log(amanda_calculate(1, 2, 5));
console.log(tyler_calculate(2));

2.4 模块类型

Node.js中的模块分为三种类型:核心模块、文件模块和npm模块。具体信息如下表所示:
| 类型 | 传递给require的字符串 | 示例 |
| ---- | ---- | ---- |
| 核心模块 | 不以 / ./ ../ 开头 | require('fs') require('os') |
| 文件模块 | 以 / ./ ../ 开头 | require('./debug.js') require('/full/path/to/module.js') |
| npm模块 | 不是核心模块且不以 / ./ ../ 开头 | require('debug') require('express') |

部分核心模块,如 process buffer 是全局可用的,不需要显式的 require 语句。核心模块的详细信息如下表:
| 模块 | 全局 | 描述 |
| ---- | ---- | ---- |
| assert | 否 | 用于测试目的 |
| buffer | 是 | 用于输入/输出(I/O)操作 |
| child_process | 否 | 运行外部程序的函数 |
| cluster | 否 | 利用多进程提高性能 |
| crypto | 否 | 内置加密库 |
| dns | 否 | 域名系统(DNS)函数 |
| domain | 否 | 分组I/O和异步操作以隔离错误 |
| events | 否 | 支持异步事件的实用工具 |
| fs | 否 | 文件系统操作 |
| http | 否 | HTTP服务器及相关实用工具 |
| https | 否 | HTTPS服务器及相关实用工具 |
| net | 否 | 异步套接字网络API |
| os | 否 | 操作系统实用工具 |
| path | 否 | 文件系统路径名实用工具 |
| punycode | 否 | 使用有限ASCII子集编码Unicode |
| querystring | 否 | 解析和构造URL查询字符串的实用工具 |
| readline | 否 | 交互式I/O实用工具 |
| smalloc | 否 | 显式分配缓冲区内存 |
| stream | 是 | 基于流的数据传输 |
| string_decoder | 否 | 将缓冲区转换为字符串 |
| tls | 否 | 传输层安全(TLS)通信实用工具 |
| tty | 否 | 低级电传打字机(TTY)函数 |
| dgram | 否 | 用户数据报协议(UDP)网络实用工具 |
| url | 是 | URL解析实用工具 |
| util | 否 | 内部Node.js实用工具 |
| vm | 否 | 虚拟(JavaScript)机 |
| zlib | 否 | 压缩实用工具 |

2.5 自定义模块

模块通常导出对象或单个函数,还有一种常见的模式是导出一个立即调用的函数。例如, debug 模块就是这种模式的典型代表:

const debug = require('debug')('main');
debug("starting");

我们也可以实现自己的 debug 模块:

let lastMessage;
module.exports = function(prefix) {
    return function(message) {
        const now = Date.now();
        const sinceLastMessage = now - (lastMessage || now);
        console.log(`${prefix} ${message} +${sinceLastMessage}ms`);
        lastMessage = now;
    }
}

2.6 多次导入模块

在Node.js中,同一个模块只会被导入一次。即使多次导入同一个模块,也会使用相同的实例。例如:

const debug1 = require('./debug')('one');
const debug2 = require('./debug')('two');
debug1('started first debugger!')
debug2('started second debugger!')
setTimeout(function() {
    debug1('after some time...');
    debug2('what happens?');
}, 200);

2.7 文件系统访问

Node.js提供了访问文件系统的功能,以下是创建和读取文件的示例:

// write.js
const fs = require('fs');
const path = require('path');
fs.writeFile(path.join(__dirname, 'hello.txt'),
        'hello from Node!', function(err) {
    if(err) return console.error('Error writing to file.');
});

// read.js
const fs = require('fs');
const path = require('path');
fs.readFile(path.join(__dirname, 'hello.txt'),
        { encoding: 'utf8' }, function(err, data) {
    if(err) return console.error('Error reading file.');
    console.log('File contents:');
    console.log(data);
});

同时, fs 模块中的函数都有同步版本,以 Sync 结尾,如 writeFileSync readFileSync

3 文件系统操作流程分析

3.1 文件创建流程

下面是使用 Node.js 创建文件的详细流程:

graph TD;
    A[开始] --> B[引入 fs 和 path 模块];
    B --> C[使用 path.join 拼接文件路径];
    C --> D[调用 fs.writeFile 写入文件];
    D --> E{是否出错};
    E -- 是 --> F[输出错误信息];
    E -- 否 --> G[文件创建成功];
    G --> H[结束];
    F --> H;

具体代码如下:

const fs = require('fs');
const path = require('path');
fs.writeFile(path.join(__dirname, 'hello.txt'),
    'hello from Node!', function(err) {
        if(err) return console.error('Error writing to file.');
    });

3.2 文件读取流程

读取文件的流程如下:

graph TD;
    A[开始] --> B[引入 fs 和 path 模块];
    B --> C[使用 path.join 拼接文件路径];
    C --> D[调用 fs.readFile 读取文件];
    D --> E{是否出错};
    E -- 是 --> F[输出错误信息];
    E -- 否 --> G[获取文件内容];
    G --> H[输出文件内容];
    H --> I[结束];
    F --> I;

代码示例:

const fs = require('fs');
const path = require('path');
fs.readFile(path.join(__dirname, 'hello.txt'),
    { encoding: 'utf8' }, function(err, data) {
        if(err) return console.error('Error reading file.');
        console.log('File contents:');
        console.log(data);
    });

4 模块系统总结与应用场景

4.1 模块系统总结

Node.js 的模块系统为开发者提供了强大的代码组织和复用能力。核心模块由 Node.js 本身提供,文件模块是开发者自定义的文件,npm 模块则是从 npm 仓库下载的第三方模块。不同类型的模块通过 require 函数进行引入,具体规则如下表:
| 模块类型 | 引入规则 | 示例 |
| ---- | ---- | ---- |
| 核心模块 | 不以 / ./ ../ 开头 | require('fs') |
| 文件模块 | 以 / ./ ../ 开头 | require('./debug.js') |
| npm 模块 | 不是核心模块且不以 / ./ ../ 开头 | require('debug') |

4.2 模块应用场景

  • 核心模块 :适用于处理操作系统、文件系统、网络等底层操作。例如,使用 fs 模块进行文件读写,使用 http 模块创建服务器。
  • 文件模块 :用于组织项目内部的代码,将不同功能的代码封装在不同的文件中,提高代码的可维护性。例如,将业务逻辑、工具函数等封装成独立的文件模块。
  • npm 模块 :可以引入第三方的优秀库和框架,快速实现各种功能。例如,使用 express 框架搭建 Web 服务器,使用 debug 模块进行调试。

5 jQuery 与 Node.js 的结合应用思路

5.1 前端与后端的协同

在现代 Web 开发中,jQuery 常用于前端页面的交互和样式操作,而 Node.js 则用于后端服务器的开发。两者可以结合使用,实现前后端的协同开发。例如,前端使用 jQuery 发送 Ajax 请求到 Node.js 服务器,服务器处理请求并返回数据给前端。
以下是一个简单的示例:
前端代码(使用 jQuery 发送 Ajax 请求):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jQuery + Node.js Example</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        $(document).ready(function() {
            $.get('http://localhost:7070').then(
                function(data) {
                    $('body').append('<p>' + data + '</p>');
                },
                function(err) {
                    console.error(err);
                }
            );
        });
    </script>
</head>
<body>

</body>
</html>

后端代码(使用 Node.js 创建服务器):

const http = require('http');

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello from Node.js server!');
});

server.listen(7070, 'localhost', () => {
    console.log('Server running at http://localhost:7070/');
});

5.2 开发流程建议

在结合使用 jQuery 和 Node.js 进行开发时,可以遵循以下流程:
1. 前端设计 :使用 jQuery 设计前端页面的交互效果和样式,规划好需要与后端交互的功能点。
2. 后端搭建 :使用 Node.js 搭建服务器,处理前端发送的请求,进行数据处理和业务逻辑实现。
3. 接口对接 :确保前端和后端的接口一致,前端发送的请求能够被后端正确处理,后端返回的数据能够被前端正确解析。
4. 测试优化 :对整个系统进行测试,发现并解决可能存在的问题,优化性能和用户体验。

通过以上的流程和方法,可以充分发挥 jQuery 和 Node.js 的优势,开发出高效、稳定的 Web 应用程序。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值