# 59. 前端之JS - jQuery库框架
# jQuery介绍
jQuery介绍:
- jQuery是一个轻量级的、兼容多浏览器的JavaScript库。
- jQuery使用户能够更方便地处理HTML Document、Events、实现动画效果、方便地进行Ajax交互,能够极大地简化JavaScript编程。它的宗旨就是:“Write less, do more.“,用最少的代码做最多的事
# jQuery地址
jQuery官网:https://jquery.com/
jQueryAP中文文档:http://jquery.cuishifeng.cn/
带min的版本js文件是压缩过的js文件
# jQuery的优势
jQuery的优势:
- 一款轻量级的JS框架。jQuery核心js文件才几十kb,不会影响页面加载速度。
- 丰富的DOM选择器,jQuery的选择器用起来很方便,比如要找到某个DOM对象的相邻元素,JS可能要写好几行代码,而jQuery一行代码就搞定了,再比如要将一个表格的隔行变色,jQuery也是一行代码搞定。
- 链式表达式。jQuery的链式操作可以把多个操作写在一行代码里,更加简洁。
- 事件、样式、动画支持。jQuery还简化了js操作css的代码,并且代码的可读性也比js要强。
- Ajax操作支持。jQuery简化了AJAX操作,后端只需返回一个JSON格式的字符串就能完成与前端的通信。
- 跨浏览器兼容。jQuery基本兼容了现在主流的浏览器,不用再为浏览器的兼容问题而伤透脑筋。
- 插件扩展开发。jQuery有着丰富的第三方的插件,例如:树形菜单、日期控件、图片切换插件、弹出窗口等等基本前端页面上的组件都有对应插件,并且用jQuery插件做出来的效果很炫,并且可以根据自己需要去改写和封装插件,简单实用。
# jQuery功能
jQuery功能:
- 选择器
- 筛选器
- 样式操作
- 文本操作
- 属性操作
- 文档处理
- 事件
- 动画效果
- 插件
- each、data、Ajax
# jQuery版本
- 1.x:兼容IE678,使用最为广泛的,官方只做BUG维护,功能不再新增。因此一般项目来说,使用1.x版本就可以了,最终版本:1.12.4 (2016年5月20日)
- 2.x:不兼容IE678,很少有人使用,官方只做BUG维护,功能不再新增。如果不考虑兼容低版本的浏览器可以使用
- 2.x,最终版本:2.2.4 (2016年5月20日)
- 3.x:不兼容IE678,只支持最新的浏览器。需要注意的是很多老的jQuery插件不支持3.x版。目前该版本是官方主要更新维护的版本。
维护IE678是一件让人头疼的事情,一般我们都会额外加载一个CSS和JS单独处理。值得庆幸的是使用这些浏览器的人也逐步减少,PC端用户已经逐步被移动端用户所取代,如果没有特殊要求的话,一般都会选择放弃对678的支持。
一般使用只有1x 跟 3x 版本
# jQuery的使用
# jQuery的导入
注意:要先导入在使用
<script src="jquery-3.3.1.min.js"></script> //在当前目录中获取文件
<script src="https://cdn.bootcss.com/jquery/3.4.1/core.js"></script> //在bootcdn官网上的jquery文件
// 实际项目不推荐使用外部的js文件
# jQuery对象
jQuery对象就是通过jQuery包装DOM对象后产生的对象。jQuery对象是 jQuery独有的。
如果一个对象是 jQuery对象,那么它就可以使用jQuery里的方法:例如$(“#i1”).html()。
$("#i1").html() :的意思是:获取id值为 i1的元素的html代码。其中 html()是jQuery里的方法。
相当于: document.getElementById("i1").innerHTML;
虽然 jQuery对象是包装 DOM对象后产生的,但是 jQuery对象无法使用 DOM对象的任何方法,同理 DOM对象也没不能使用 jQuery里的方法。
一个约定,我们在声明一个jQuery对象变量的时候在变量名前面加上$:
var $variable = jQuery对像
var variable = DOM对象
# jQuery对象和DOM对象的相互转换使用
$("#i1").html(); //jQuery对象可以使用jQuery的方法
$("#i1")[0].innerHTML; // DOM对象使用DOM的方法
$variable[0] //jQuery对象转成DOM对象
$(this); // 把DOM对象转换成jQuery对象
# jQuery基础语法
$(selector).action()
# 查找标签
# 基本选择器
# id选择器:
$("#id")
# 标签选择器:
$("tagName")
# class选择器:
$(".className")
# 配合使用:
$("div.c1") // 找到有c1 class类的div标签
# 所有元素选择器:
$("*")
# 组合选择器:
$("#id, .className, tagName")
# 层级选择器
x和y可以为任意选择器
$("x y"); // x的所有后代y(子子孙孙)
$("x > y"); // x的所有儿子y(儿子)
$("x + y"); // 找到所有紧挨在x后面的y
$("x ~ y"); // x之后所有的兄弟y
# 基本筛选器
:first // 取第一个
$("input:first");
:last // 取最后一个
$("input:last");
:eq(index) // 索引等于index的那个元素
$("input:eq(2)");
:even // 匹配所有索引值为偶数的元素,从 0 开始计数
$("input:even");
:odd // 匹配所有索引值为奇数的元素,从 0 开始计数
$("input:odd");
:gt(index) // 匹配所有大于给定索引值的元素
$("input:gt(1)");
:lt(index) // 匹配所有小于给定索引值的元素
$("input:lt(1)");
:not(元素选择器) // 移除所有满足not条件的标签
$("li:not(.c1)") // 找到所有不包含c1样式类的li标签
$("li:not(:has(a))") // 找到所有后代中不含a标签的li标签
:has(元素选择器) // 选取所有包含一个或多个标签在其内的标签(指的是从后代元素找)
$("div:has(h1)") // 找到所有后代中有h1标签的div标签
$("div:has(.c1)") // 找到所有后代中有c1样式类的div标签
# 实例 - 自定义模态框,使用jQuery实现弹出和隐藏功能
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>自定义模态框</title>
<style>
.cover {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: darkgrey;
z-index: 999;
}
.modal {
width: 600px;
height: 400px;
background-color: white;
position: fixed;
left: 50%;
top: 50%;
margin-left: -300px;
margin-top: -200px;
z-index: 1000;
}
.hide {
display: none;
}
</style>
</head>
<body>
<input type="button" value="弹" id="i0">
<div class="cover hide"></div>
<div class="modal hide">
<label for="i1">姓名</label>
<input id="i1" type="text">
<label for="i2">爱好</label>
<input id="i2" type="text">
<input type="button" id="i3" value="关闭">
</div>
<script src="jquery-3.3.1.min.js"></script>
<script>
var tButton = $("#i0")[0];
tButton.onclick=function () {
var coverEle = $(".cover")[0];
var modalEle = $(".modal")[0];
$(coverEle).removeClass("hide");
$(modalEle).removeClass("hide");
};
var cButton = $("#i3")[0];
cButton.onclick=function () {
var coverEle = $(".cover")[0];
var modalEle = $(".modal")[0];
$(coverEle).addClass("hide");
$(modalEle).addClass("hide");
}
</script>
</body>
</html>
# 属性选择器
[attribute]
[attribute=value]// 属性等于
[attribute!=value]// 属性不等于
// 示例
<input type="text">
<input type="password">
<input type="checkbox">
$("[s14]"); //取到有s14属性的标签
$("[s14='sss']"); //取到有s14属性的参数等于sss的标签
$("input[type='checkbox']"); // 取到checkbox类型的input标签
$("input[type!='text']"); // 取到类型不是text的input标签
# 表单筛选器
:text
:password
:file
:radio
:checkbox
:submit
:reset
:button
// 有没有很熟悉,都是在input中的参数
$(":checkbox") // 找到所有的checkbox
$("input:checkbox") // 找到所有input中包含checkbox的标签
# 表单对象属性
:enabled
:disabled
:checked
:selected
例子:
找到可用的input标签
<form>
<input name="email" disabled="disabled" />
<input name="id" />
</form>
$("input:enabled") // 找到可用的input标签
找到被选中的option:
<select id="s1">
<option value="beijing">北京市</option>
<option value="shanghai">上海市</option>
<option selected value="guangzhou">广州市</option>
<option value="shenzhen">深圳市</option>
</select>
$(":selected") // 找到所有被选中的option
# 筛选器方法
# 查找上一个元素
$("#id").prev() // 找到id同级的上一个元素
$("#id").prevAll() //找到id同级的所有前面的元素
$("#id").prevUntil("#i2") //找到id跟i2之间同级的所有元素,如果终止元素找不到,会直接找到最前面后返回所有在找的过程记录的标签
# 查找下一个元素
$("#id").next() // 找到id同级的下一个元素
$("#id").nextAll() //找到id下同级的所有元素
$("#id").nextUntil("#i2") //找到id跟i2之间同级的所有元素,如果终止元素找不到,会直接找到最后面后返回所有在找的过程记录的标签
# 查找父亲元素
$("#id").parent() // 查看id的上一个父标签
$("#id").parents() // 查找当前id的所有的父标签
$("#id").parentsUntil("html") // 查找当前id的所有的父标签,直到遇到匹配的那个html元素为止。
# 查找儿子和兄弟元素
$("#id").children(); // 儿子们 找到id下的所有标签
$("#id").siblings(); // 兄弟们 找到同级的所有标签,结果不包含当前查找的id
# 查找
搜索所有与指定表达式匹配的元素。这个函数是找出正在处理的元素的后代元素的好方法。
在后代查找符合要求的
$("div").find("p")
//等价于
$("div p")
//二种查找结果相同一样
# 筛选
筛选出与指定表达式匹配的元素集合。这个方法用于缩小匹配的范围。用逗号分隔多个表达式。
根据条件对已经找到的结果进行二次过滤
筛选属性
.filter() // 从结果集中过滤出有c1样式类的
.first() // 获取匹配的第一个元素
.last() // 获取匹配的最后一个元素
.not() // 从匹配元素的集合中删除与指定表达式匹配的元素
.has() // 保留包含特定后代的元素,去掉那些不含有指定后代的元素。
.eq() // 索引值等于指定值的元素
例如
$("div").filter(".c1") // 从结果集中过滤出有c1样式类的
//等价于
$("div.c1")
# 用变量作为$()里面的id值
var a = "d1"
$("#" + a)
# 操作标签
# 样式操作
addClass(); // 添加指定的CSS类名。
removeClass(); // 移除指定的CSS类名。
hasClass(); // 判断样式存不存在
toggleClass(); // 切换CSS类名,如果有就移除,如果没有就添加。
$(".cover").removeClass("hide"); // 移除 .cover中的class类中的hide样式
# 实例 - 弹出框
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<title>Title</title>
<style>
.cover {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.4);
z-index: 99;
}
.modal {
width: 700px;
height: 400px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -350px;
margin-top: -200px;
background-color: white;
z-index: 100;
}
.close {
float: right;
margin-right: 15px;
margin-top: 10px;
font-size: 16px;
}
.hide {
display: none;
}
</style>
</head>
<body>
<button id="b1">点我弹出</button>
<div class="cover hide"></div>
<div class="modal hide">
<span class="close" id="s1">x</span>
</div>
<script src="jquery-3.3.1.min.js"></script>
<script>
var b1Ele = $("#b1")[0];
var $coverEle = $(".cover");
var $modalEle = $(".modal");
b1Ele.onclick=function (ev) {
$coverEle.removeClass("hide");
$modalEle.removeClass("hide");
};
var s1Ele = document.getElementById("s1");
s1Ele.onclick=function (ev) {
$coverEle.addClass("hide");
$modalEle.addClass("hide");
}
</script>
</body>
</html>
# CSS样式操作
css("color","red")//DOM操作:tag.style.color="red"
$("p").css("color", "red"); //将所有p标签的字体设置为红色
// 批量css设置
$("p").css({"color":"red","font-size":"24px"}); //将所有p标签的字体设置为红色并大小设置为24像素
# 位置操作
offset() // 获取匹配元素在当前窗口的相对偏移或设置元素位置
$(".c1").offset() //获取当前窗口的相对偏移值
position() // 获取匹配元素相对父元素的偏移
$(".c1").position() //获取当前标签跟父标签之间相对的偏移值
scrollTop() // 获取匹配元素相对滚动条顶部的偏移
scrollLeft() // 获取匹配元素相对滚动条左侧的偏移
// .offset()方法允许我们检索一个元素相对于文档(document)的当前位置。
// 和 .position()的差别在于: .position()是相对于相对于父级元素的位移。
# 实例 - 返回顶部
重点代码
<script src="jquery-3.2.1.min.js"></script>
<script>
$("#b1").on("click", function () {
$(".c1").offset({left: 200, top:200});
});
$(window).scroll(function () {
if ($(window).scrollTop() > 100) {
$("#b2").removeClass("hide");
}else {
$("#b2").addClass("hide");
}
});
$("#b2").on("click", function () {
$(window).scrollTop(0);
})
</script>
全部代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>位置相关示例之返回顶部</title>
<style>
.c1 {
width: 100px;
height: 200px;
background-color: red;
}
.c2 {
height: 50px;
width: 50px;
position: fixed;
bottom: 15px;
right: 15px;
background-color: #2b669a;
}
.hide {
display: none;
}
.c3 {
height: 100px;
}
</style>
</head>
<body>
<button id="b1" class="btn btn-default">点我</button>
<div class="c1"></div>
<div class="c3">1</div>
<div class="c3">2</div>
<div class="c3">3</div>
<div class="c3">4</div>
<div class="c3">5</div>
<div class="c3">6</div>
<div class="c3">7</div>
<div class="c3">8</div>
<div class="c3">9</div>
<div class="c3">10</div>
<div class="c3">11</div>
<div class="c3">12</div>
<div class="c3">13</div>
<div class="c3">14</div>
<div class="c3">15</div>
<div class="c3">16</div>
<div class="c3">17</div>
<div class="c3">18</div>
<div class="c3">19</div>
<div class="c3">20</div>
<button id="b2" class="btn btn-default c2 hide">返回顶部</button>
<script src="jquery-3.2.1.min.js"></script>
<script>
$("#b1").on("click", function () {
$(".c1").offset({left: 200, top:200});
});
$(window).scroll(function () {
if ($(window).scrollTop() > 100) {
$("#b2").removeClass("hide");
}else {
$("#b2").addClass("hide");
}
});
$("#b2").on("click", function () {
$(window).scrollTop(0);
})
</script>
</body>
</html>
# 尺寸操作
height() //获取匹配元素的高度是多少
$(".c1").height()
width() //获取匹配元素的宽度是多少
$(".c1").width()
innerHeight() //获取匹配元素的高度 + 内填充的高度(上下高度相加)
$(".c1").innerHeight()
innerWidth() //获取匹配元素的宽度 + 内填充的宽度(左右宽度相加)
$(".c1").width()
outerHeight() //获取匹配元素的高度 + 内填充的高度(上下高度相加) + 边框的高度(上下高度相加)
$(".c1").outerHeight()
outerWidth() //获取匹配元素的宽度 + 内填充的宽度(左右宽度相加) + 边框的高度(左右宽度相加)
$(".c1").width()
# HTML文本操作
# HTML代码
html()// 取得第一个匹配元素的html内容
$("d1").html() // 获取第一个匹配上d1的html内容 注意,是第一个匹配上的
html(val)// 设置所有匹配元素的html内容
$(".d1").html("<p>你好</p>") // 修改所有匹配上d1的标签的文本值
# 文本值
text()// 取得所有匹配元素的内容
$("#d1").text() //查看di的文本内容,包含换行符跟空格
text(val)// 设置所有匹配元素的内容
$("#d1").text("哈哈哈哈") //将d1的文本内容替换成指定的字符
# 值
val()// 取得第一个匹配元素的当前值
val(val)// 设置所有匹配元素的值
val([val1, val2])// 设置多选的checkbox、多选select的值
例如:
<input type="checkbox" value="basketball" name="hobby">篮球
<input type="checkbox" value="football" name="hobby">足球
<select multiple id="s1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
$("[name='hobby']").val(['basketball', 'football']);
$("#s1").val(["1", "2"])
示例:
获取被选中的checkbox或radio的值:
<label for="c1">女</label>
<input name="gender" id="c1" type="radio" value="0">
<label for="c2">男</label>
<input name="gender" id="c2" type="radio" value="1">
$("input[name='gender']:checked").val()
# 属性操作
# 用于ID等或自定义属性:
attr(attrName)// 返回第一个匹配元素的属性值
attr(attrName, attrValue)// 为所有匹配元素设置一个属性值
attr({k1: v1, k2:v2})// 为所有匹配元素设置多个属性值
removeAttr()// 从每一个匹配的元素中删除一个属性
# 用于checkbox和radio
prop() // 获取属性, 选中返回true, 没选中返回false
removeProp() // 移除属性
$(":checkbox").prop("checked",true) // 让找到的标签全部选中
# 注意事项
在1.x及2.x版本的jQuery中使用attr对checkbox进行赋值操作时会出bug,在3.x版本的jQuery中则没有这个问题。
为了兼容性,我们在处理checkbox和radio的时候尽量使用特定的prop(),不要使用attr("checked", "checked")。
<input type="checkbox" value="1">
<input type="radio" value="2">
<script>
$(":checkbox[value='1']").prop("checked", true);
$(":radio[value='2']").prop("checked", true);
</script>
# prop和attr的区别
attr全称:attribute(属性)
prop全称:property(属性)
虽然都是属性,但他们所指的属性并不相同,
- attr所指的属性是HTML标签属性,
- 而prop所指的是DOM对象属性,
- 可以认为attr是显式的,
- 而prop是隐式的。
# 举例:
<input type="checkbox" id="i1" value="1">
$("#i1").attr("checked") // undefined
$("#i1").prop("checked") // false
可以看到attr获取一个标签内没有的东西会得到undefined,而prop获取的是这个DOM对象的属性,因此checked为false。
如果换成下面的代码:
<input type="checkbox" checked id="i1" value="1">
$("#i1").attr("checked") // checked
$("#i1").prop("checked") // true
这已经可以证明attr的局限性,它的作用范围只限于HTML标签内的属性,而prop获取的是这个DOM对象的属性,选中返回true,没选中返回false。
接下来再看一下针对自定义属性,attr和prop又有什么区别:
<input type="checkbox" checked id="i1" value="1" me="自定义属性">
$("#i1").attr("me") // "自定义属性"
$("#i1").prop("me") // undefined
可以看到prop不支持获取标签的自定义属性。
# 总结一下:
- 对于标签上有的能看到的属性和自定义属性都用attr
- 对于返回布尔值的比如checkbox、radio和option的是否被选中都用prop。
# 文档处理
文档处理,在jQuery是无法直接创建标签的,就只能借助原生js来创建标签,在使用jQuery来添加标签
# 添加到指定元素 - 内部的 - 后面
$(A).append(B)// 把B追加到A
$(A).appendTo(B)// 把A追加到B
//实例:
// 假如有一个ul标签,里面有li标签
var liel = document.createElement("li") //创建一个li标签
liel.innerText = "哈喽" // 给创建的li标签赋值
$("#ul").append(liel) // 将创建的li标签添加到指定的位置的内部的后面
# 添加到指定元素 - 内部的 - 前面
$(A).prepend(B)// 把B前置到A
$(A).prependTo(B)// 把A前置到B
//实例:
var liel = document.createElement("li") //创建一个li标签
liel.innerText = "哈喽" // 给创建的li标签赋值
$("#ul").prepend(liel) // 将创建的li标签添加到指定的位置的内部的前面
# 添加到指定元素 - 外部的 - 后面
$(A).after(B)// 把B放到A的后面
$(A).insertAfter(B)// 把A放到B的后面
//实例:
var liel = document.createElement("div") //创建一个div标签
liel.innerText = "哈喽" // 给创建的div标签赋值
$("#ul").after(liel) // 将创建的div标签添加到指定的位置的外部的后面
# 添加到指定元素 - 外部的 - 前面
$(A).before(B)// 把B放到A的前面
$(A).insertBefore(B)// 把A放到B的前面
//实例:
var liel = document.createElement("div") //创建一个div标签
liel.innerText = "哈喽" // 给创建的div标签赋值
$("#ul").before(liel) // 将创建的div标签添加到指定的位置的外部的前面
# 移除所有匹配上的元素
remove()// 从DOM中删除所有匹配的元素。
$("#v1").remove() //删除id为v1的标签,包含内部子标签
# 清空所有匹配上的元素的内部标签
empty()// 删除匹配的元素集合中所有的子节点。
$("#v1").empty() //清空v1标签的所有子标签
# 替换
replaceWith() //替换
replaceAll() //用什么替换谁,跟上面的相反
//实例:
var aliel = document.createElement("a") //创建一个a标签
$(aliel).attr("href","http://92.linux91.cn") //给创建的a标签属性
liel.innerText = "MSG" // 给创建的a标签赋值
$("a").replaceWith(aliel) // 将创建的div标签添加到指定的位置的外部的前面
# 克隆(复制)
clone() // 复制, 复制出来就相当跟创建标签一样,不会直接出现在html上, 而是等待添加
// true参数, 代表把复制的标签连带事件也一起复制
// 实例:
$("#b1").clone() //复制, 等到b1的同相标签,等待添加
$("#b1").clone().insertBefore("#b1") //把b1的标签复制一份出来,在添加到b1的外部的后面去
# 实例 - 复制按钮
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>克隆</title>
<style>
#b1 {
background-color: deeppink;
padding: 5px;
color: white;
margin: 5px;
}
#b2 {
background-color: dodgerblue;
padding: 5px;
color: white;
margin: 5px;
}
</style>
</head>
<body>
<button id="b1">屠龙宝刀,点击就送</button>
<hr>
<button id="b2">屠龙宝刀,点击就送</button>
<script src="jquery-3.2.1.min.js"></script>
<script>
// clone方法不加参数true,克隆标签但不克隆标签带的事件
$("#b1").on("click", function () {
$(this).clone().insertAfter(this);
});
// clone方法加参数true,克隆标签并且克隆标签带的事件
$("#b2").on("click", function () {
$(this).clone(true).insertAfter(this);
});
</sc ript>
</body>
</html>
# jQuery事件
# 常用事件
//点击事件 --- 最最常用的事件
click(function(){...})
// 键盘事件
keydown(function(){...}) //键盘按下的事件
// 每个键盘的键都一个独立的编号,如果不用这编号,可以先打印对象.keyCode方法来获取键盘键的编号
// 常用keyCode: 空格 32 Enter 13 ESC 27 shift 16
keyup(function(){...}) //键盘抬起的事件
// 鼠标事件
hover(function(){...},function(){...}) //hover是jQuery封装二个原生事件而生的事件
//需要写二个方法(函数)
//第一个,鼠标移进来触发
//第二个,鼠标移出去触发
//二个原生事件
// mouseenter:绑定鼠标进入事件
// mouseleave:绑定鼠标划出事件
// 监听input输入值变化事件
blur(function(){...}) //blur事件,只能等input框失去聚焦,才会触发
$("标签标识").on("input",function(){...}) //input事件,只要input框中的值发生变化,就会触发
focus(function(){...}) // 元素聚焦事件
focusout(function(){...}) // 元素失去聚焦事件
change(function(){...}) // 元素框中的值发生变化是触发事件
# 事件绑定
# 直接事件绑定
$(标签对象).事件(function(){
})
# 使用on进行事件绑定 - 用于未来的标签
未来的标签:就是说没有写入在html文档中的标签,在程序的执行中,创建的标签,就叫做未来的标签,未来的标签需要js事件的支持,所以需要使用on来设置固定不变的父标签,由父标签来代调用执行
$(固定父标签对象).on("事件", "子选择器(未来标签的标识)",function(){
})
# 移除事件
.off( events [, selector ][,function(){}])
off()
方法移除用 .on()
绑定的事件处理程序。
- events: 事件
- selector: 选择器(可选的)
- function: 事件处理函数
# 事件冒泡
在标签请求事件时,会一层接一层的向上请求,如果上层中也有事件,那么就会一层一层的接着触发事件
<div id="d1">
<p id="p1">
<input type="submit" id="s1">
</p>
</div>
<script src="jquery-3.3.1.js"></script>
<script>
$("#d1").click(function () {
alert("div");
});
$("#p1").click(function () {
alert("ppp")
});
$("#s1").click(function (e) {
alert("sss");
})
</script>
可以尝试下以上的代码, 会发现, 点击提交按钮, 会让你确定三次
# 阻止事件冒泡
使用stopPropagation()方法来阻止事件冒泡
<div id="d1">
<p id="p1">
<input type="submit" id="s1">
</p>
</div>
<script src="jquery-3.3.1.js"></script>
<script>
$("#d1").click(function () {
alert("div");
});
$("#p1").click(function () {
alert("ppp")
});
$("#s1").click(function (e) {
alert("sss");
// 阻止事件向上级传递
e.stopPropagation();
})
</script>
# 事件委托-让js创建的标签拥有事件
当文件运行时创建一个标签,或是一个按钮时,并设置它的class类d1,那么d1的事件在创建按钮的前面,那么这个事件绑定的元素就没有新创建的标签,就算他的类是d1,那也没用,这时就要使用到事件委托
事件委托是通过事件冒泡的原理,利用父标签去捕获子标签的事件。
这时就要使用on进行事件绑定的方式
$("父标签").on("事件", "选择器", function () {
})
//父标签: 一般使用body
//选择器: 接上面比如, 写新创建的标签的class类中的名, 就是d1
//这样子, 当新创建的标签被触发, 就会一直找, 直到找到可以找到事件的父标签, 这由父标签来触发这个事项,
//也跟script标签的位置有关
# 阻止默认事件的执行
在标签中,有一些是带有默认的事件的,比如submit按钮,点击后,执行自定义事项结束后,就会执行它默认的事项,提交刷新事项,让页面提交信息并刷新
使用对象.preventDefault()对象来阻止默认事件的执行
对象.preventDefault();
# 实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>阻止默认事件</title>
</head>
<body>
<form action="">
<button id="b1">点我</button>
</form>
<script src="jquery-3.3.1.min.js"></script>
<script>
$("#b1").click(function (e) {
alert(123);
//return false;
e.preventDefault();
});
</script>
</body>
</html>
# 阻止后续事件的执行
一个标签可以绑定很多个事件,事件的执行顺序,按文档的顺序执行,这时如果有一个判断事项,如果判断结果为false,就不用执行接下来的事项,那么就可以使用return false,返回一个false,这标签接下来的事项就不执行
return false
# 键盘事件 - keydown和keyup事件组合示例
有一个表格,可以让人多选几行数据,
- 如果按下shift,来设置状态,那么选中的数据全部发生变化,
- 如果没有按下shift,那么就只是单行数据发生变化,
- 如果按下shift,但是在操作的那行上,并没有选中,那么只是单行数据发生变化
# 重点代码
<script>
// flag变量,用于多事件中键盘指定的键的状态
var flag = false;
// shift按键被按下的时候
$(window).keydown(function (event) {
console.log(event.keyCode);
if (event.keyCode === 16){
flag = true;
}
});
// shift按键被抬起的时候
$(window).keyup(function (event) {
console.log(event.keyCode);
if (event.keyCode === 16){
flag = false;
}
});
// select标签的值发生变化的时候
$("select").change(function (event) {
// 如果shift按键被按下,就进入批量编辑模式
// shift按键对应的code是16
// 判断当前select这一行是否被选中
console.log($(this).parent().siblings().first().find(":checkbox"));
// 获取操作那行是否被选中
var isChecked = $(this).parent().siblings().first().find(":checkbox").prop("checked");
console.log(isChecked);
// 判断,flag跟isChecked都为true
// flag为true,代表shift键一直被按着
// isChecked为true,代表操作那行被选中
if (flag && isChecked) {
// 进入批量编辑模式
// 1. 取到当前select选中的值
var value = $(this).val();
// 2. 给其他被选中行的select设置成和我一样的值
// 2.1 找到那些被选中行的select
var $select = $("input:checked").parent().parent().find("select")
// 2.2 给选中的select赋值
$select.val(value);
}
});
</script>
# 全部代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<title>Title</title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>#</th>
<th>姓名</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox"></td>
<td>Egon</td>
<td>
<select>
<option value="1">上线</option>
<option value="2">下线</option>
<option value="3">停职</option>
</select>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Alex</td>
<td>
<select>
<option value="1">上线</option>
<option value="2">下线</option>
<option value="3">停职</option>
</select>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Yuan</td>
<td>
<select>
<option value="1">上线</option>
<option value="2">下线</option>
<option value="3">停职</option>
</select>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>EvaJ</td>
<td>
<select>
<option value="1">上线</option>
<option value="2">下线</option>
<option value="3">停职</option>
</select>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Gold</td>
<td>
<select>
<option value="1">上线</option>
<option value="2">下线</option>
<option value="3">停职</option>
</select>
</td>
</tr>
</tbody>
</table>
<input type="button" id="b1" value="全选">
<input type="button" id="b2" value="取消">
<input type="button" id="b3" value="反选">
<script src="jquery-3.3.1.js"></script>
<script>
var flag = false;
// shift按键被按下的时候
$(window).keydown(function (event) {
console.log(event.keyCode);
if (event.keyCode === 16){
flag = true;
}
});
// shift按键被抬起的时候
$(window).keyup(function (event) {
console.log(event.keyCode);
if (event.keyCode === 16){
flag = false;
}
});
// select标签的值发生变化的时候
$("select").change(function (event) {
// 如果shift按键被按下,就进入批量编辑模式
// shift按键对应的code是16
// 判断当前select这一行是否被选中
console.log($(this).parent().siblings().first().find(":checkbox"));
// 获取操作那行是否被选中
var isChecked = $(this).parent().siblings().first().find(":checkbox").prop("checked");
console.log(isChecked);
// 判断,flag跟isChecked都为true
// flag为true,代表shift键一直被按着
// isChecked为true,代表操作那行被选中
if (flag && isChecked) {
// 进入批量编辑模式
// 1. 取到当前select选中的值
var value = $(this).val();
// 2. 给其他被选中行的select设置成和我一样的值
// 2.1 找到那些被选中行的select
var $select = $("input:checked").parent().parent().find("select")
// 2.2 给选中的select赋值
$select.val(value);
}
});
</script>
</body>
</html>
# 鼠标事件 - hover事件
页面上有个购物车的字符,只要鼠标移上下,下面就会出现一个小框,记录着购物车的信息
# 重点代码
<script>
// 第一种写法
$(".cart").hover(
function () {
// 鼠标移进来
$(".shop-cart").css("display", "block");
},
function () {
// 鼠标移出去
$(".shop-cart").css("display", "none");
}
);
// 第二种写法
$(".cart").hover(
function () {
$(this).addClass("hover");
},
function () {
$(this).removeClass("hover");
}
);
</script>
# 全部代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<title>Title</title>
<style>
body {
margin: 0;
}
.menu {
height: 50px;
width: 100%;
background-color: #0f0f0f;
color: darkgray;
}
.menu>ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.menu>ul>li {
float: left;
line-height: 50px;
margin-right: 15px;
position: relative;
}
.shop-cart {
background-color: #00a9ff;
color: white;
height: 50px;
width: 100px;
position: absolute;
right: 0;
display: none;
}
.hover>.shop-cart {
display: block;
}
</style>
</head>
<body>
<div class="menu">
<ul>
<li>登录</li>
<li>注册</li>
<li class="cart">购物车
<div class="shop-cart">
空空如也~
</div>
</li>
</ul>
</div>
<script src="jquery-3.3.1.js"></script>
<script>
$(".cart").hover(
function () {
$(this).addClass("hover");
},
function () {
$(this).removeClass("hover");
}
);
</script>
</body>
</html>
# 基于原生的二个事件
像click、keydown等DOM中定义的事件,我们都可以使用.on()
方法来绑定事件,但是hover
这种jQuery中定义的事件就不能用.on()
方法来绑定了。
想使用事件委托的方式绑定hover事件处理函数,可以参照如下代码分两步绑定事件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<title>Title</title>
<style>
body {
margin: 0;
}
.menu {
height: 50px;
width: 100%;
background-color: #0f0f0f;
color: darkgray;
}
.menu>ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.menu>ul>li {
float: left;
line-height: 50px;
margin-right: 15px;
position: relative;
}
.shop-cart {
background-color: #00a9ff;
color: white;
height: 50px;
width: 100px;
position: absolute;
right: 0;
display: none;
}
.hover>.shop-cart {
display: block;
}
</style>
</head>
<body>
<div class="menu">
<ul>
<li>登录</li>
<li>注册</li>
<li class="cart">购物车
<div class="shop-cart">
空空如也~
</div>
</li>
</ul>
</div>
<script src="jquery-3.3.1.js"></script>
<script>
$('.menu').on('mouseenter', '.cart', function() {//绑定鼠标进入事件
$(this).addClass('hover');
});
$('.menu').on('mouseleave', '.cart', function() {//绑定鼠标划出事件
$(this).removeClass('hover');
});
</script>
</body>
</html>
# 实时监听input输入值变化事件 - input事件
创建一个input框,使用blur事件跟input事件进行监听,分别看一下二个事件的区别
# 重点代码
<script>
// input框失去焦点就触发
$("#i1").blur(function () {
var value = $(this).val();
console.log(value);
});
// 只要input框的值发生变化就触发
$("#i1").on("input", function () {
var value = $(this).val();
console.log(value);
})
</script>
# 全部代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<title>Title</title>
</head>
<body>
<input type="text" id="i1">
<script src="jquery-3.3.1.js"></script>
<script>
// input框失去焦点就触发
$("#i1").blur(function () {
var value = $(this).val();
console.log(value);
});
// 只要input框的值发生变化就触发
$("#i1").on("input", function () {
var value = $(this).val();
console.log(value);
})
</script>
</body>
</html>
# 等待文档标签加载完毕在执行js代码
# 原生js的写法
<script>
window.onload = function () {
//页面加载完之后要执行的js代码
}
</script>
# jQuery中的写法
<script>
$(document).ready(function () {
//页面加载完之后要执行的js代码
})
</script>
# jQuery动画效果
// 基本
show([s,[e],[fn]]) //显示
$("#l1").show(5000) // 让图片在5秒内慢慢的变大显示
hide([s,[e],[fn]]) //隐藏
$("#l1").hide(5000) // 让图片在5秒内慢慢的变小隐藏
toggle([s],[e],[fn]) //取反
$("#l1").fadeToggle(5000) // 如果图片存在就采用5秒内显示,如果图片不存在就采用5秒内隐藏
// 滑动
slideDown([s],[e],[fn]) //展开
$("#l1").slideDown(5000) //让图片在5秒内,从上到下慢慢的展开显示
slideUp([s,[e],[fn]]) //收起
$("#l1").slideUp(5000) //让图片在5秒内,从下到上慢慢的收起隐藏
slideToggle([s],[e],[fn]) //取反
$("#l1").fadeToggle(5000) // 如果图片存在就采用5秒内收起,如果图片不存在就采用5秒内展开
// 淡入淡出
fadeIn([s],[e],[fn]) //淡入
$("#l1").fadeOut(5000) //让图片在5秒内,整体慢慢的变成不透明显示
fadeOut([s],[e],[fn]) //淡出
$("#l1").fadeOut(5000) //让图片在5秒内,整体慢慢的变成透明消失隐藏
fadeTo([[s],o,[e],[fn]]) //控制透明的值
$("#l1").fadeOut(5000,0.3) //让图片在5秒内,整体慢慢的变成透明0.3的程度
fadeToggle([s,[e],[fn]]) //取反
$("#l1").fadeToggle(5000) // 如果图片存在就采用5秒内淡出,如果图片不存在就采用5秒内淡入
// 自定义(了解即可)
animate(p,[s],[e],[fn]) //自定义动画,下面有实例
# 自定义动画实例 - 简单点赞特效
简单 - 点赞特效
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>点赞动画示例</title>
<style>
div {
position: relative;
display: inline-block;
}
div>i {
display: inline-block;
color: red;
position: absolute;
right: -16px;
top: -5px;
opacity: 1;
}
</style>
</head>
<body>
<div id="d1">点赞</div>
<script src="jquery-3.2.1.min.js"></script>
<script>
$("#d1").on("click", function () {
var newI = document.createElement("i");
newI.innerText = "+1";
$(this).append(newI);
$(this).children("i").animate({
opacity: 0
}, 1000)
})
</script>
</body>
</html>
# jQuery补充
# .each()循环
# $.each()循环数组
jQuery.each(collection, callback(indexInArray, valueOfElement)):
描述:
- 一个通用的迭代函数,它可以用来无缝迭代对象和数组。
- 数组和类似数组的对象通过一个长度属性(如一个函数的参数对象)来迭代数字索引,从0到length - 1。
- 其他对象通过其属性名进行迭代。
li =[10,20,30,40]
$.each(li,function(i, v){
console.log(i, v);//index是索引,ele是每次循环的具体元素。
})
输出:
010
120
230
340
# .each()循环一个jQuery对象
描述:遍历一个jQuery对象,为每个匹配元素执行一个函数。
.each() 方法用来迭代jQuery对象中的每一个DOM元素。每次回调函数执行时,会传递当前循环次数作为参数(从0开始计数)。由于回调函数是在当前DOM元素为上下文的语境中触发的,所以关键字 this 总是指向这个元素。
// 为每一个li标签添加foo
$("li").each(function(){
$(this).addClass("c1");
});
注意: jQuery的方法返回一个jQuery对象,遍历jQuery集合中的元素 - 被称为隐式迭代的过程。
当这种情况发生时,它通常不需要显式地循环的 .each() 方法:
也就是说,上面的例子没有必要使用each()方法,直接像下面这样写就可以了:
$("li").addClass("c1"); // 对所有标签做统一操作
# 跳起当前循环,进入下一次循环
在遍历过程中可以使用 return 跳起当前循环,进入下一次循环
跳起each循环
return ;
# 结束循环
在遍历过程中可以使用 return false
提前结束each循环。
终止each循环
return false;
# .data()标签中存储数据
在匹配的元素集合中的所有元素上存储任意相关数据或返回匹配的元素集合中的第一个元素的给定名称的数据存储的值。
.data(key, value):
描述:在匹配的元素上存储任意相关数据。
$("div").data("k",100);//给所有div标签都保存一个名为k,值为100
.data(key):
描述: 返回匹配的元素集合中的第一个元素的给定名称的数据存储的值—通过 .data(name, value) 或 HTML5 data-* 属性设置。
$("div").data("k");//返回第一个div标签中保存的"k"的值
.removeData(key):
描述:移除存放在元素上的数据,不加key参数表示移除所有保存的数据。
$("div").removeData("k"); //移除元素上存放k对应的数据
# jQuery插件(了解即可)
jQuery.extend(object)
jQuery的命名空间下添加新的功能。多用于插件开发者向 jQuery 中添加新函数时使用。
示例:
<script>
jQuery.extend({
min:function(a, b){return a < b ? a : b;},
max:function(a, b){return a > b ? a : b;}
});
jQuery.min(2,3);// => 2
jQuery.max(4,5);// => 5
</script>
jQuery.fn.extend(object)
一个对象的内容合并到jQuery的原型,以提供新的jQuery实例方法。
<script>
jQuery.fn.extend({
check:function(){
return this.each(function(){this.checked =true;});
},
uncheck:function(){
return this.each(function(){this.checked =false;});
}
});
// jQuery对象可以使用新添加的check()方法了。
$("input[type='checkbox']").check();
</script>
单独写在文件中的扩展:
(function(jq){
jq.extend({
funcName:function(){
...
},
});
})(jQuery);
# 实例 - 自定义的jQuery登录验证插件
# HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>登录校验示例</title>
<style>
.login-form {
margin: 100px auto 0;
max-width: 330px;
}
.login-form > div {
margin: 15px 0;
}
.error {
color: red;
}
</style>
</head>
<body>
<div>
<form action="" class="login-form" novalidate>
<div>
<label for="username">姓名</label>
<input id="username" type="text" name="name" required autocomplete="off">
<span class="error"></span>
</div>
<div>
<label for="passwd">密码</label>
<input id="passwd" type="password" name="password" required autocomplete="off">
<span class="error"></span>
</div>
<div>
<label for="mobile">手机</label>
<input id="mobile" type="text" name="mobile" required autocomplete="off">
<span class="error"></span>
</div>
<div>
<label for="where">来自</label>
<input id="where" type="text" name="where" autocomplete="off">
<span class="error"></span>
</div>
<div>
<input type="submit" value="登录">
</div>
</form>
</div>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="validate.js"></script>
<script>
$.validate();
</script>
</body>
</html>
# JS代码
"use strict";
(function ($) {
function check() {
// 定义一个标志位,表示验证通过还是验证不通过
var flag = true;
var errMsg;
// 校验规则
$("form input[type!=':submit']").each(function () {
var labelName = $(this).prev().text();
var inputName = $(this).attr("name");
var inputValue = $(this).val();
if ($(this).attr("required")) {
// 如果是必填项
if (inputValue.length === 0) {
// 值为空
errMsg = labelName + "不能为空";
$(this).next().text(errMsg);
flag = false;
return false;
}
// 如果是密码类型,我们就要判断密码的长度是否大于6位
if (inputName === "password") {
// 除了上面判断为不为空还要判断密码长度是否大于6位
if (inputValue.length < 6) {
errMsg = labelName + "必须大于6位";
$(this).next().text(errMsg);
flag = false;
return false;
}
}
// 如果是手机类型,我们需要判断手机的格式是否正确
if (inputName === "mobile") {
// 使用正则表达式校验inputValue是否为正确的手机号码
if (!/^1[345678]\d{9}$/.test(inputValue)) {
// 不是有效的手机号码格式
errMsg = labelName + "格式不正确";
$(this).next().text(errMsg);
flag = false;
return false;
}
}
}
});
return flag;
}
function clearError(arg) {
// 清空之前的错误提示
$(arg).next().text("");
}
// 上面都是我定义的工具函数
$.extend({
validate: function () {
$("form :submit").on("click", function () {
return check();
});
$("form :input[type!='submit']").on("focus", function () {
clearError(this);
});
}
});
})(jQuery);
# 实例 - 传参版插件
# HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>登录校验示例</title>
<style>
.login-form {
margin: 100px auto 0;
max-width: 330px;
}
.login-form > div {
margin: 15px 0;
}
.error {
color: red;
}
</style>
</head>
<body>
<div>
<form action="" class="login-form" novalidate>
<div>
<label for="username">姓名</label>
<input id="username" type="text" name="name" required autocomplete="off">
<span class="error"></span>
</div>
<div>
<label for="passwd">密码</label>
<input id="passwd" type="password" name="password" required autocomplete="off">
<span class="error"></span>
</div>
<div>
<label for="mobile">手机</label>
<input id="mobile" type="text" name="mobile" required autocomplete="off">
<span class="error"></span>
</div>
<div>
<label for="where">来自</label>
<input id="where" type="text" name="where" autocomplete="off">
<span class="error"></span>
</div>
<div>
<input type="submit" value="登录">
</div>
</form>
</div>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="validate3.js"></script>
<script>
$.validate({"name":{"required": true}, "password": {"required": true, "minLength": 8}, "mobile": {"required": true}});
</script>
</body>
</html>
# JS代码
"use strict";
(function ($) {
function check(arg) {
// 定义一个标志位,表示验证通过还是验证不通过
var flag = true;
var errMsg;
// 校验规则
$("form input[type!=':submit']").each(function () {
var labelName = $(this).prev().text();
var inputName = $(this).attr("name");
var inputValue = $(this).val();
if (arg[inputName].required) {
// 如果是必填项
if (inputValue.length === 0) {
// 值为空
errMsg = labelName + "不能为空";
$(this).next().text(errMsg);
flag = false;
return false;
}
// 如果是密码类型,我们就要判断密码的长度是否大于6位
if (inputName === "password") {
// 除了上面判断为不为空还要判断密码长度是否大于6位
if (inputValue.length < arg[inputName].minLength) {
errMsg = labelName + "必须大于"+arg[inputName].minLength+"位";
$(this).next().text(errMsg);
flag = false;
return false;
}
}
// 如果是手机类型,我们需要判断手机的格式是否正确
if (inputName === "mobile") {
// 使用正则表达式校验inputValue是否为正确的手机号码
if (!/^1[345678]\d{9}$/.test(inputValue)) {
// 不是有效的手机号码格式
errMsg = labelName + "格式不正确";
$(this).next().text(errMsg);
flag = false;
return false;
}
}
}
});
return flag;
}
function clearError(arg) {
// 清空之前的错误提示
$(arg).next().text("");
}
// 上面都是我定义的工具函数
$.extend({
validate: function (arg) {
$("form :submit").on("click", function () {
return check(arg);
});
$("form :input[type!='submit']").on("focus", function () {
clearError(this);
});
}
});
})(jQuery);