jQuery 中的 Ajax

一、$.ajax()

1、作用:发送Ajax请求。

 $.ajax({
     type: 'get',
     url: 'http://www.example.com',
     data: { name: 'zhangsan', age: '20' },
     contentType: 'application/x-www-form-urlencoded',
     beforeSend: function () { 
         return false
     },
     success: function (response) {},
     error: function (xhr) {}
});
//除了上面所示的传递对象值之外,也可以传递字符串参数值
 {data: 'name=zhangsan&age=20'}
//传递json格式的参数 
{contentType: 'application/json'}
//转换为json对象字符串
JSON.stringify({name: 'zhangsan', age: '20'})

2、作用:发送jsonp请求。

$.ajax({
    url: 'http://www.example.com',
    // 指定当前发送jsonp请求
    dataType: 'jsonp',
    // 修改callback参数名称
    jsonp: 'cb',
    // 指定函数名称
    jsonCallback: 'fnName',
    success: function (response) {} 
})

3、serialize方法

作用:将表单中的数据自动拼接成字符串类型的参数。

var params = $('#form').serialize();
// name=zhangsan&age=30

二、$.get()、$.post

作用:$.get方法用于发送get请求,$.post方法用于发送post请求。

//第一个参数是请求地址 第二个参数向服务器端传递的参数(对象或字符串) 第三个参数是回调函数(实际上是success函数)
//若无需向服务器端传参数则可以省略第二个参数
$.get('http://www.example.com', {name: 'zhangsan', age: 30}, function (response) {}) 
$.post('http://www.example.com', {name: 'lisi', age: 22}, function (response) {})

三、Todo案例

1、为todo数据库添加账号

  1. 使用mongo命令进入mongodb数据库
  2. 使用use admin命令进入到admin数据中
  3. 使用db.auth(‘root’, ‘root’)命令登录数据库
  4. 使用use todo命令切换到todo数据库
  5. 使用db.createUser({user: ‘itcast’, pwd: ‘itcast’, roles: [‘readWrite’]})创建todo数据库账号
  6. 使用exit命令退出mongodo数据库

2、展示任务列表

  1. 准备一个放置任务列表的数组
  2. 向服务器端发送请求,获取已存在的任务
  3. 将已存在的任务存储在任务列表数组中
  4. 通过模板引擎将任务列表数组中的任务显示在页面中

3、添加任务

  1. 为文本框绑定键盘抬起事件,在事件处理函数中判断当前用户敲击的是否是回车键
  2. 当用户敲击回车键的时候,判断用户在文本框中是否输入了任务名称
  3. 向服务器端发送请求,将用户输入的任务名称添加到数据库中,同时将任务添加到任务数组中
  4. 通过模板引擎将任务列表数组中的任务显示在页面中

4、删除任务

  1. 为删除按钮添加点击事件
  2. 在事件处理函数中获取到要删任务的id
  3. 向服务器端发送请求,根据ID删除任务,同时将任务数组中的相同任务删除
  4. 通过模板引擎将任务列表数组中的任务重新显示在页面中

5、更改任务状态

  1. 为任务复选框添加onchange事件
  2. 在事件处理函数中获取复选框是否选中
  3. 向服务器端发送请求,将当前复选框的是否选中状态提交到服务器端
  4. 将任务状态同时也更新到任务列表数组中
  5. 通过模板引擎将任务列表数组中的任务重新显示在页面中并且根据任务是否完成为li元素添加completed类名

6、修改任务名称

  1. 为任务名称外层的label标签添加双击事件,同时为当前任务外层的li标签添加editing类名,开启编辑状态
  2. 将任务名称显示在文本框中并让文本框获取焦点
  3. 当文本框离开焦点时,将用户在文本框中输入值提交到服务器端,并且将最新的任务名称更新到任务列表数组中
  4. 使用模板引擎重新渲染页面中的任务列表

7、计算未完成任务数量

  1. 准备一个用于存储未完成任务数量的变量
  2. 将未完成任务从任务数组中过滤出来
  3. 将过滤结果数组的长度赋值给任务数量变量
  4. 将结果更新到页面中

8、显示未完成任务

  1. 为active按钮添加点击事件
  2. 从任务列表数组中将未完成任务过滤出来
  3. 使用模板引擎将过滤结果显示在页面中

9、清除已完成任务

  1. 为clear completed按钮添加点击事件
  2. 向服务器端发送请求将数据库中的已完成任务删除掉
  3. 将任务列表中的已完成任务删除调用
  4. 使用模板引擎将任务列表中的最后结果显示在页面中

.html

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Todo List</title>
		<link rel="stylesheet" href="assets/css/base.css">
		<link rel="stylesheet" href="assets/css/index.css">
		<link rel="stylesheet" href="/js/nprogress/nprogress.css">
	</head>
	<body>
		<section class="todoapp">
			<header class="header">
				<h1>todos</h1>
				<input type="text" class="new-todo" placeholder="What needs to be done?" autofocus id="task">
			</header>
			<!-- This section should be hidden by default and shown when there are todos -->
			<section class="main">
				<input class="toggle-all" type="checkbox">
				<ul class="todo-list" id="todo-list"></ul>
			</section>
			<!-- This footer should hidden by default and shown when there are todos -->
			<footer class="footer">
				<!-- This should be `0 items left` by default -->
				<span class="todo-count"><strong id="count">0</strong> item left</span>
				<!-- Remove this if you don't implement routing -->
				<ul class="filters">
					<li>
						<a class="selected" href="javascript:;">All</a>
					</li>
					<li>
						<a href="javascript:;">Active</a>
					</li>
					<li>
						<a href="javascript:;">Completed</a>
					</li>
				</ul>
				<!-- Hidden if no completed items are left ↓ -->
				<button class="clear-completed">Clear completed</button>
			</footer>
		</section>
		<script src="/js/jquery.min.js"></script>
		<script src="/js/template-web.js"></script>
		<script src="/js/nprogress/nprogress.js"></script>
		<!-- 任务列表模板 -->
		<script type="text/html" id="taskTpl">
			{{each tasks}}
			<li class="{{$value.completed ? 'completed' : ''}}">
				<div class="view">
					<input class="toggle" type="checkbox" {{$value.completed ? 'checked' : ''}}>
					<label>{{$value.title}}</label>
					<button class="destroy" data-id="{{$value._id}}"></button>
				</div>
				<input class="edit">
			</li>
			{{/each}}
		</script>
		<script type="text/javascript">
			// 用于存放任务列表的数组
			var taskAry = [];
			// 选择任务列表容器
			var taskBox = $('#todo-list');
			// 添加任务的文本框
			var taskInp = $('#task');
			// 用于存储未完成任务数量的strong标签
			var strong = $('#count');

			// 当页面中有ajax请求发送时触发
			$(document).on('ajaxStart', function () {
				 NProgress.start() 
			})

			// 当页面中有ajax请求完成时触发
			$(document).on('ajaxComplete', function () {
				NProgress.done() 
			})

			// 向服务器端发送请求 获取已经存在的任务
			$.ajax({
				url: '/todo/task',
				type: 'get',
				success: function (response) {
					// 将已存在的任务存储在taskAry变量中
					taskAry = response;
					// 拼接字符串 将拼接好的字符串显示在页面中
					render();
					// 计算未完成任务数量
					calcCount ()
				}
			})

			// 获取文本框并且添加键盘抬起事件
			taskInp.on('keyup', function (event) {
				// 如果用户敲击的是回车键
				if (event.keyCode == 13) {
					// 判断用户是否在文本框中输入了任务名称
					var taskName = $(this).val();
					// 如果用户没有在文本框中输入内容
					if (taskName.trim().length == 0) {
						alert('请输入任务名称')
						// 阻止代码向下执行
						return;
					}
					// 向服务器端发送请求 添加任务
					$.ajax({
						type: 'post',
						url: '/todo/addTask',
						contentType: 'application/json',
						data: JSON.stringify({title: taskName}),
						success: function (response) {
							// 将任务添加到任务列表中
							taskAry.push(response);
							// 拼接字符串 将拼接好的字符串显示在页面中
							render();
							// 清空文本框中的内容
							taskInp.val('');
							// 计算未完成任务数量
							calcCount ()
						}
					})
				}
			});

			// 拼接字符串 将拼接好的字符串显示在页面中
			function render() {
				// 字符串拼接
				var html = template('taskTpl', {
					tasks: taskAry
				});
				// 将拼接好的字符串显示在ul标签中
				taskBox.html(html);
			}

			// 当用户点击删除按钮时触发ul标签身上的点击事件
			taskBox.on('click', '.destroy', function () {
				// 要删除的任务的id
				var id = $(this).attr('data-id');
				// 向服务器端发送请求删除 任务
				$.ajax({
					url: '/todo/deleteTask',
					type: 'get',
					data: {
						_id: id
					},
					success: function (response) {
						// 从任务数组中找到已经删除掉的任务的索引
						var index = taskAry.findIndex(item => item._id == id);
						// 将任务从数组中删除
						taskAry.splice(index, 1);
						// 重新将任务数组中的元素显示在页面中
						render();
						// 计算未完成任务数量
						calcCount ()
					}
				})
			});

			// 当用户改变任务名称前面的复选框状态时触发
			taskBox.on('change', '.toggle', function () {
				// 代表复选框是否选中 true 选中 false 未选中的
				const status = $(this).is(':checked');
				// 当前点击任务的id
				const id = $(this).siblings('button').attr('data-id');
				// 向服务器端发送请求 更改任务状态
				$.ajax({
					type: 'post',
					url: '/todo/modifyTask',
					data: JSON.stringify({_id: id, completed: status}),
					contentType: 'application/json',
					success: function (response) {
						// 将任务状态同步到任务数组中
						var task = taskAry.find(item => item._id == id);
						// 更改任务状态
						task.completed = response.completed;
						// 将数组中任务的最新状态更新到页面中
						render();
						// 计算未完成任务数量
						calcCount ()
					}
				})
			});

			// 当双击事件名称的时候触发
			taskBox.on('dblclick', 'label', function () {
				// 让任务处于编辑状态
				$(this).parent().parent().addClass('editing');
				// 将任务名称显示在文本框中
				$(this).parent().siblings('input').val($(this).text())
				// 让文本框获取焦点
				$(this).parent().siblings('input').focus();
			})

			// 当文本框离开焦点的时候
			taskBox.on('blur', '.edit', function () {
				// 最新的任务名称
				var newTaskName = $(this).val();
				// 编辑任务的id
				var id = $(this).siblings().find('button').attr('data-id');
				// 向服务器端发送请求 修改任务名称
				$.ajax({
					url: '/todo/modifyTask',
					type: 'post',
					data: JSON.stringify({_id: id, title: newTaskName}),
					contentType: 'application/json',
					success: function (response) {
						// 将当期任务的最新状态同步到任务数组中
						var task = taskAry.find(item => item._id == id);
						// 修改任务名称
						task.title = response.title;
						// 将任务数组中的任务同步到页面中
						render();
						// 计算未完成任务数量
						calcCount ()
					}
				})
			});

			// 用于计算未完成任务的数量
			function calcCount () {
				// 存储结果的变量
				var count = 0;
				// 将未完成的任务过滤到一个新的数组中
				var newAry = taskAry.filter(item => item.completed == false);
				// 将新数组的长度赋值给count
				count = newAry.length;
				// 将未完成的任务数量显示在页面中
				strong.text(count)
			}

		</script>
	</body>
</html>

todo.js

// 引入express框架
const express = require('express');
// 工具库
const _ = require('lodash');
// 对象校验
const Joi = require('joi');
// 创建todo案例路由
const todoRouter = express.Router();
// 导入todo集合构造函数
const Task = require('../model/task');

// 获取任务列表
todoRouter.get('/task', async (req, res) => {
	const task = await Task.find();
	// 响应
	res.send(task);
});

// 添加任务
todoRouter.post('/addTask', async (req, res) => {
	// 接收客户端传递过来的任务名称
	const { title } = req.body;
	// 验证规则
	const schema = {
		title: Joi.string().required().min(2).max(30)
	};
	// 验证客户端传递过来的请求参数 
	const { error } = Joi.validate(req.body, schema);
	// 验证失败
	if (error) {
		// 将错误信息响应给客户端
		return res.status(400).send({message: error.details[0].message})
	}
	// 创建任务实例
	const task = new Task({title: title, completed: false});
	// 执行插入操作
	await task.save();
	// 响应
	setTimeout(() => {
		res.send(task);
	}, 2000)
});

// 删除任务
todoRouter.get('/deleteTask', async (req, res) => {
	// 要删除的任务id
	const { _id } = req.query;
	// 验证规则
	const schema = {
		_id: Joi.string().required().regex(/^[0-9a-fA-F]{24}$/)
	}
	// 验证客户端传递过来的请求参数 
	const { error } = Joi.validate(req.query, schema);
	// 验证失败
	if (error) {
		// 将错误信息响应给客户端
		return res.status(400).send({message: error.details[0].message})
	}
	// 删除任务
	const task = await Task.findOneAndDelete({_id: _id});
	// 响应
	res.send(task);
});

// 清除已完成任务
todoRouter.get('/clearTask', async (req, res) => {
	// 执行清空操作
	const result = await Task.deleteMany({completed: true});
	// 返回清空数据
	res.send(result);
});

// 修改任务
todoRouter.post('/modifyTask', async (req, res) => {
	// 执行修改操作
	const task = await Task.findOneAndUpdate({_id: req.body._id}, _.pick(req.body, ['title', 'completed']),{new: true})
	// 响应
	res.send(task);
});

// 查询未完成任务数量
todoRouter.get('/unCompletedTaskCount', async (req, res) => {
	// 执行查询操作
	const result = await Task.countDocuments({completed: false});
	// 响应
	res.send({num: result})
});

// 更改任务全部状态
todoRouter.get('/changeAllTasksComplete', async (req, res) => {
	// 状态
	const { status } = req.query;
	// 执行更改状态操作
	const result = await Task.updateMany({}, {completed: status});
	// 响应
	res.send(result);
});

// 将todo案例路由作为模块成员进行导出
module.exports = todoRouter;

四、jQuery中Ajax全局事件

全局事件

只要页面中有Ajax请求被发送,对应的全局事件就会被触发。

.ajaxStart()     // 当请求开始发送时触发
.ajaxComplete()  // 当请求完成时触发

NProgress(插件)

纳米级进度条,使用逼真的涓流动画来告诉用户正在发生的事情。

<link rel='stylesheet' href='nprogress.css'/>
<script src='nprogress.js'></script>
NProgress.start();  // 进度条开始运动 
NProgress.done();   // 进度条结束运动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YiRano_0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值