版本
- 关于
.js
和.min.js
.js
未压缩的含源码版本,通常用于本地开发
.min.js
压缩版,体积小,所以通常用于线上
- jQuery的几个版本系列
1.x
可以兼容IE678,最终版为1.12.4(推荐)
2.x
将1.x中的兼容IE678部分的代码删除,即不再兼容IE678
3.x
不兼容IE678,同步js并新增了一些api
jQuery的入口函数
- 入口函数
可以理解为是一个事件,当页面加载完成时执行
- jQuery的入口函数
$(document).ready(function () { //... });
可简写为以下代码:
$(function () { //... });
- 对比js原生的
window.onload
- window.onload存在覆盖问题
window.onload = function(){ //不会生效,被后面的onload覆盖 console.log(1) }; window.onload = function(){ console.log(2) };
$(document).ready(function () { //生效 console.log(1); }); $(function () { //生效 console.log(2); });
- jQuery的优先级高,即会先执行
- 原生入口需要等待页面和外部资源都加载完毕,而jQuery只需等待页面加载完成即可
jQuery对象和DOM对象
- DOM对象
指通过原生js方法获取的元素对象,这种DOM对象无法使用jQuery对象的属性和方法
- jQuery对象
指通过
$()
方式获取的元素对象,同样的jQuery对象也无法使用DOM对象的属性和方法,另外jQuery对象是个伪数组,而伪数组下标对应的值为一个个DOM对象,
- 两种对象的转换
- DOM转jQuery
$(DOM对象)
,注意,该DOM对象可以是多个对象,如直接传入querySelectorAll
的结果
- jQuery转DOM
通过
$()[index]
或使用get()
方法
jQuery的两大特点
隐式迭代
指一种隐式的遍历操作
- 对于设置性操作
默认会获取所有的元素,并进行一样的设置操作,所以如果想对每个元素进行不同的设置操作,需要手动进行遍历并设置
- 对于获取性操作
只会获取并返回第一个元素的相关值
链式编程
- 对于设置性操作
由于内部进行了
return this;
,所以可以进行链式调用
- 对于获取性操作
由于返回值为获取的那个值,不再是原来的jQuery对象,所以不可以继续链式调用
prevObject 和 end()
链式使用示例
$(this).text("☆").prevAll().text("五角星"); //由于.prevAll()为获取操作,且获取的对象不再是原来的对象($(this)),所以$(this)的链式直到调用到这里
使用
prevObject
属性实现继续链式调用$(this).text("☆").prevAll().text("★").prevObject.nextAll().text("☆"); //prevObject属性可以返回上一个jQuery对象
使用
end()
方法实现继续链式调用$(this).text("★").prevAll().text("★").end().nextAll().text("☆"); //end()方法是对prevObject属性的封装,表示当前对象调用结束,返回前一个jQuery对象
$
- 说明
是一个函数,也可以用
jQuery
来表示,功能很强大,会根据传入的参数不同而起到不同的效果
- 作用
- 参数为选择器:获取元素
- 参数为函数:入口函数
- 参数为DOM对象:将DOM对象转为jQuery对象
- 参数为HTML字符串:创建节点
jQuery的选择器
过滤选择器
:odd
:下标为奇数的元素$("ul > li:odd"); //筛选出下标为奇数的li标签
even
:下标为偶数的元素:first
:第一个元素:last
:最后一个元素:eq(下标)
:指定下标的元素:checked
:input[radio]或input[checkbox]中被选中的元素:selected
:下拉框中被选中的option标签
筛选选择器
children(selector)
:子代选择器$("ul").children("li"); //获取ul下的所有直接li子元素
find(selector)
:后代选择器$("ul").find("li"); //获取ul下的所有li子元素
siblings(selector)
:兄弟选择器(不含自身)next()
:下一个兄弟节点nextAll()
:当前元素之后的所有兄弟节点prev()
:上一个兄弟节点prevAll()
:当前元素之前的所有兄弟节点parent()
:查找父节点parent(selector)
:查找指定父节点eq(index)
:选中指定下标元素$("ul > li").eq(2); //下标从0开始,所以是筛选出$("ul > li")结果的第3个li
jQuery常用属性/方法
show()
:展示hide()
:隐藏slideDown()
:向下展开slideUp()
:向上展开index()
获取元素下标(当前元素在所有兄弟中的索引)
get(index)
和eq一样可以获取到具体下标的元素,不过获取到的是一个DOM对象
css()
:设置样式
- 设置单个样式:
css(样式名, 样式值)
$("div").css("fontSize", "20px"); //样式名需要用小驼峰式命名
- 设置多个样式:
css({样式名1: 样式值1, 样式名2: 样式值2})
$("div").css({"fontSize": "20", "color": "pink"}); //此时px单位可以省略
- 获取样式:
css(样式名)
$("div").css("fontSize"); //如果选中的div有多个,则获取到的是第一个(div)元素的样式值
addClass(类名)
:添加类名(不会影响已有类名)removeClass(类名)
:移除类名(不会影响已有类名)hasClass(类名)
:是否包含类名如果调用的对象包含多个元素,则只需要其中一个元素包含即可
toggleClass(类名)
:有则移除,无则添加attr()
:属性操作
- 说明
属性指的是如img标签的width、title等属性,上面的css只对应style属性
- 设置单个属性
attr(属性名, 属性值)
- 设置多个属性
attr({属性名1: 属性值1, 属性名2: 属性值2})
- 获取属性
attr(属性名)
,如果找不到则返回undefined
- 移除属性
removeAttr(属性名)
prop()
:属性操作使用方式和
attr()
一样,只不过通常用来获取checkbox, selected, disabled
这3个属性,其他属性的获取建议使用attr()
text()
和html()
:修改文字内容
text()
:相当于 innerText()html()
:相当于 innerHTML()
play()
和load()
:播放音视频由H5提供,jQuery并未进行封装,所以只能用dom对象播放,此外play方法的调用还有个前提,就是要和页面进行互动,如单击了页面,在此前提下才有权限调用此方法,而且在使用play之前可以先使用load方法,用于加载资源,该方法一样由H5提供,jQuery没有进行封装,需要用dom对象调用
val()
获取或设置表单元素的值,如input、textarea等的value属性值
- 获取值
$("input").val(); //无参即表示获取值
- 设置值
$("input").val("abc");
width()
和height()
获取或设置宽高,注意如果元素尚未添加到页面仍在内存中,值为零,如新创建的元素
- 获取宽高
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> div { width: 100px; height: 100px; padding: 20px; background-color: skyblue; border: 5px solid salmon; margin: 5px; } </style> </head> <body> <div></div> <script src="jquery/jquery.js"></script> <script> const $div = $('div'); console.log($div.height()); //100 content console.log($div.innerHeight()); //140 content + padding console.log($div.outerHeight()); //150 content + padding + border console.log($div.outerHeight(true)); //160 content + padding + border + margin console.log($div.width()); //100 content console.log($div.innerWidth()); //140 content + padding console.log($div.outerWidth()); //150 content + padding + border console.log($div.outerWidth(true)); //160 content + padding + border + margin </script> </body> </html>
- 设置宽高
$("img").height(200)
- 获取可视区(页面)的宽高
$(window).width(); $(window).height();
scrollLeft()
和scrollTop()
- 获取卷区距离
scrollLeft()
:获取水平卷区距离scrollTop()
:获取垂直卷区距离
- 设置卷区距离
scrollLeft(10)
- 结合动画时的使用
jQuery的scrollTop方法可以认为是对
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
的封装,其中window.pageYOffset是只读属性,且它没有scrollTop属性,所以修改操作只能针对后两个
$(document.documentElement, document.body).animate({scrollTop: 0}, 1000); //并集选择器 //简写形式 $("html", "body").animate({scrollTop: 0}, 1000);
offset()
和position()
offset()
获取元素
document(页面)
的距离,如body中的一个div,默认有body的8个margin的距离
position()
获取元素距离有定位的父元素的位置
- 示例
$(selector).offset()
,返回值是个对象,如{left: 100, top: 200}
jQuery的遍历方式
- for循环
- each循环
let $lis = $("ul > li"); $lis.each(function(index, element) { console.log(index, element) });
jQuery的动画
指jQuery的show、slide、fade三组基本动画,另外只支持数值型动画,其他动画需要使用插件实现
- show系列动画
所有参数皆可选,无参则无动画效果
show(speed, easing, callback); //显示元素 hide(speed, easing, callback); //隐藏元素 toggle(speed, easing, callback); //展示和隐藏的切换 /* * speed:速度,这里表示动画时长,单位毫秒,常用取值有 fast(表示200毫秒)、normal(默认400)、slow(600) * easing:动画效果,取值有 swing(默认,慢-快-慢,类似钟摆效果)、linear(匀速) * callback:动画结束时的回调函数 */
- slide系列动画
所有参数皆可选,无参则无动画效果
slideDown(speed, easing, callback); //向下展示 slideUp(speed, easing, callback); //向上展示 slideToggle(speed, easing, callback); //上面两者的切换 /* * speed:速度,这里表示动画时长,单位毫秒,常用取值有 fast(表示200毫秒)、normal(默认,400)、slow(600) * easing:动画效果,取值有 swing(默认,慢-快-慢,类似钟摆效果)、linear(匀速) * callback:动画结束时的回调函数 */
- fade系列动画
所有参数皆可选,无参则无动画效果
fadeIn(speed, easing, callback); //淡入 fadeOut(speed, easing, callback); //淡出 fadeToggle(speed, easing, callback); //上面两者的切换 /* * speed:速度,这里表示动画时长,单位毫秒,常用取值有 fast(表示200毫秒)、normal(默认,400)、slow(600) * easing:动画效果,取值有 swing(默认,慢-快-慢,类似钟摆效果)、linear(匀速) * callback:动画结束时的回调函数 */
- 自定义动画
animate(obj, speed, easing, callback); /* * obj:必填,需要进行动画的样式和样式值(它们将同时进行动画) * 其他参数:选填,含义同三组基本动画 */
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> div { width: 100px; height: 100px; background-color: pink; position: relative; } </style> </head> <body> <div></div> <script src="jquery/jquery.js"></script> <script> let $box = $("div"); //jQuery的变量一般设置为用$开头 $box.animate( {left: 500, width: 200, height: 200 }, 1000, "swing", () => {alert("done.")} ) </script> </body> </html>
- 动画队列:左移500再圆角50%
- 方式一:使用回调函数
$box.animate( {left: 500}, () => { box.animate({borderRadius: "50%"}) } )
- 方式二:使用动画队列
可以更好地指定动画顺序,但存在鼠标和动画不同步的问题
$box .animate({left: 500}) .animate({borderRadius: "50%"}) .slideUp(2000);
- 动画停止
stop(clearQueue, jumpToEnd); /* * 无参:将直接停止当前正在运行的动画,如果动画队列中还存在后续动画,则直接开始改后续动画 * clearQueue:是否清楚动画队列,默认false * jumpToEnd:是否直接跳到当前要执行的动画的最终效果(如直接跑到left:500的位置上),默认false */
jQuery的节点操作
- 语法
$(html字符串)
- 创建节点
$a = $(`<a href="#">百度一下,你就知道</a>`); $("body").append($a);
- 添加节点
parentNode.append(node); //父节点追加一个子节点,相当于 appendChild(node) childNode.appendTo(parent); //同上,不过这里的parent可以直接写一个选择器 parentNode.prepend(node); //父节点添加node子节点,并将其设为第一个子节点 childNode.prependTo(parent); //同上 node1.after(node2); //将node2添加为node1最近的下一个兄弟节点 node1.before(node2); //将node2添加为node1最近的上一个兄弟节点
- 清空节点
node.empty(); //清空node标签中的所有内容,可以清空子元素上绑定的内容,推荐使用
- 删除节点
node.remove(); //删除node节点自身
- 克隆节点
node.clone(arg); //将node节点克隆一份,默认为深拷贝,arg表示是否克隆元素的事件,默认否
jQuery的事件
- 事件示例与节流阀
节流阀:只通过一个开关控制事件的执行,如实现keydown事件只执行一次
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div style="width: 100px; height: 100px; background: pink;"></div> <script src="jquery/jquery.js"></script> <script> let open = true; let $div = $("div"); $div.on('keydown', function() { if (open) { open = false; console.log("hello ~ "); } }); $div.click(function () { $div.keydown(); }); </script> </body> </html>
- 注册事件
- 方式一
这种方式存在的问题是无法解绑
$("div").click(function(){ //... })
- 方式二:
bind
这种方式存在的问题是无法动态绑定,即对于新创建的元素不会注册上事件,这时就需要使用到事件委托
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div style="width: 100px; height: 100px; background: pink;"></div> <script src="jquery/jquery.js"></script> <script> let count = 0; let $div = $("div"); $div.bind("click mouseover", function () { console.log(++count); if (count === 5) { //最终只能输出 1 - 5 //$div.unbind(); 直接解绑所有事件 $div.unbind("click mouseover"); //可以指定要解绑的事件,而且可以一次指定多个 } }) </script> </body> </html>
- 方式三:
on
这种方式是经过优化的统一注册方法
on(type, selector, data, fn); /* * type:事件类型,可一次注册多个类型 * selector:触发元素,可选,如果该值存在,表明是一个委托事件 * data:携带的数据,可选,用于事件处理函数内部使用 * fn:事件处理函数 */ off(); //解绑所有事件,包括委托事件 off(type, [selector]); //解绑指定事件,selector用于委托事件的解绑
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div style="width: 100px; height: 100px; border: 1px solid blueviolet;"> <p>hello</p> <p>hello</p> </div> <script src="jquery/jquery.js"></script> <script> $("div").on("click", "p:first", ["hello", "jQuery"], function (e) { let data = e.data; $(this).text(data.join(",")); }) </script> </body> </html>
- 事件委托(事件代理)
- 简介
指将要注册的事件不直接注册给自己,而是注册给父辈元素,自身只需要作为触发元素
- 语法
$("parentSelector").delegate("触发元素标签如p", "事件类型如click", function事件处理函数); $("parentSelector").undelegate(); //解绑parentSelector中的所有委托事件 $("parentSelector").undelegate(selector(触发元素), 事件类型); //解绑parentSelector中指定的委托事件
- 示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> div > p { color: green; text-align: center; cursor: pointer; user-select: none; } .hotpink { color: hotpink; } </style> </head> <body> <div style="width: 100px; height: 100px; border: 1px solid blueviolet;"></div> <script src="jquery/jquery.js"></script> <script> let $div = $("div"); $div.delegate("p", "click", function () { $(this).toggleClass("hotpink"); }); setTimeout(function () { let p = $(`<p>点我变色</p>`); $div.append(p); }, 3000); </script> </body> </html>
- 事件触发的两种方式
$(".box").click(); //触发点击事件
$(".box").trigger("click"); //触发点击事件
- 事件对象
- 说明
jQuery对原生js事件对象进行了封装,处理了兼容性问题
- 常用属性/方法
screenX
:到屏幕左侧的距离screenY
:到屏幕上方的距离clientX
:到页面左侧的距离(忽略滚动条)clientY
:到页面上方的距离(忽略滚动条)pageX
:到页面最左侧的距离(含卷区)pageY
:到页面最顶部的距离(含卷区)- ```even.keyCode``:键盘码
even.data
:见on事件even.stopPropagation()
:阻止事件传播even.preventDefault()
:阻止浏览器默认行为如在a标签的点击事件中最后加上这句,将不会进行跳转
- jQuery事件处理函数中使用
return false
的两个作用
- 阻止事件传播
- 阻止浏览器默认行为
jQuery的AJAX
- 常用的五个属性和四个回调函数
$.ajax({ /* 五个属性 */ type: '请求方式', url: '请求地址', data: '请求参数,可以是个对象,也可以是个查询字符串', dataType: '数据返回值类型,有text(默认)、json、xml、script等', timeout: '超时时间', /* 四个回调函数: beforeSend -> success/error -> complete */ beforeSend(){ //发送请求前的回调函数 }, success(data){ //响应成功时的回调函数,data为服务器返回的数据,类型和dataType对应(默认responseText) }, error(e){ //响应失败时的回调函数,e为错误信息 }, complete(xhr, str){ //请求完成后回调函数 (请求成功或失败之后均调用) //xhr:XMLHttpRequest对象 //str:一个描述请求类型的字符串 } });
- 表单序列化
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="#" id="form"> <input type="text" name="username"> <input type="password" name="password"> <input type="file" name="file"> <input type="button" class="send" value="send"> </form> <script src="jquery/jquery.js"></script> <script> $('.send').on('click', function () { /* 注意:无法获取文件(input:file)数据 */ console.log($('#form').serialize()); // >> username=xiaoming&password=12 }); </script> </body> </html>
- 几个快捷方法
$.get('http://localhost:56789/index'); //发送get请求 $.post('http://localhost:56789/index'); //发送post请求 console.log($.getJSON('http://localhost:56789/index')); //{一个对象},获取后台json格式结果 $.getScript(); //获取后台js文件 $("#result").load("ajax/test.html"); //可以通过AJAX请求从服务器加载数据,并把返回的数据放置到指定的元素中
- 全局事件
.ajaxSend(); //当任一ajax发送请求前触发 .ajaxError(); //当任一ajax请求错误时触发 .ajaxSuccess(); //当任一ajax请求成功时触发 .ajaxComplete(); //当任一ajax请求完成时触发 .ajaxStart(); //当第一个ajax请求开始时触发 .ajaxStop(); //当所有的ajax请求都完成时(相当于最后一个ajax完成时)触发 /* 最好不放在入口函数里面,因为可能会有执行到该全局事件代码时,前面已经产生了ajax请求 */ $(document).ajax***(function(e){ ... }); //固定写法,
- 用Promise封装AJAX
function fetch(options, $) { return new Promise(((resolve, reject) => { $.ajax({ url: options.url, data: options.data || {}, type: options.type || 'GET', dataType: 'json', success: resolve, error: reject }); })); }
jQuery的多库共存
- 说明
对于jQuery使用的
$
符号,可能有一种情况,就是其他的js库也使用了该符号导致二者造成冲突
- 方案一
用
jQuery
替代jQuery的$
- 方案二
使用
jQuery.noConflict()
方法,该方法可以释放jQuery对$
的使用,并返回$
符号的功能,通过自定义一个别名即可继续使用
jQuery的插件
- 说明
一个js文件,该文件依赖于jQuery,即使用插件前必须先引入jQuery才行
- 原理
插件的实现,核心在于将提供的方法/属性放入到jQuery的原型中
- jQuery原型的几种写法
- jQuery.prototype
- $.prototype
- jQuery.fn
- $.fn
- 常用插件
- jquery.color.js
用于实现色值型动画,支持所有的十六进制/rgb格式的颜色值,对于颜色单词,插件中给出了支持清单
- jquery.lazyload.js
用于实现图片懒加载功能,可以在有许多图片的滚动场景中,实现在滚动到指定位置才加载并显示相关图片
- jQueryPagination
分页插件