jQuery的官网:https://jquery.com/
jQuery是一种使用原生js进行封装之后的工具库
文章目录
jQuery的原理解析
jQuery实际上是js的匿名函数,里面封装了很多方法
我们在写代码的时候可以直接在全局中使用$
能够执行,上面说jQuery实际上是匿名函数,那么如何在全局中使用匿名函数的变量的变量呢???
答案是将变量绑定给window对象
JS的三大组成模块中的BOM的 Window 对象表示一个浏览器窗口或一个框架。Window 对象是全局对象,所有的表达式都在当前的环境中计算。也就是说,要引用当前窗口根本不需要特殊的语法,可以把那个窗口的属性作为全局变量来使用。例如,可以只写 document,而不必写 window.document。
实际上在jQuery中也是这么做的
在源码中可以看到jQuery同时绑定了$
和jQuery
,那么在jQuery中这两个对象就是同一个对象
console.log($ === jQuery); // ture
jQuery的使用
通过script标签引入jQuery之后再使用jQuery
jq的入口:jQuery
和$
执行方式
- jq的全局(作为对象执行):$.xxx()
$.ajax()
- jq的局部(作为函数执行)(DOM方法):$().xxx()
$(".btn").on()
$(".btn").html()
在使用jQuery和原生Js时需要注意的地方
- 对象的方法,不能通用(因为jQuery对选择元素封装成了数组,不是原生Js)
// jq
const obox2 = $(".box2");
console.log(obox2)
obox2.css("background","green");
// 原生js模拟jq封装的
const obox1 = $$(".box1");
console.log(obox1)
obox1.css("background","pink");
function $$(name){
const ele = document.querySelector(name);
ele.css = function(key,val){
ele.style[key] = val;
}
return ele;
}
-
如果需要互相使用,需要提前转换
-
jq的DOM对象转js的DOM对象
- 解析数组
- $(".box")[0]
- $(".box").get(0)
const obox2 = $("#box2");
console.log(obox2);
// jq方法
// obox2.css("background","pink")
// 解析jq的对象
// obox2[0].style.background = "yellow";
obox2.get(0).style.background = "blue";
- js的DOM对象转jq的DOM对象
- 将js的DOM对象作为参数传给jq的函数执行,返回值就是转换之后的jq的DOM对象
- $(obox)
// 原生js选择元素
const obox1 = document.querySelector("#box1");
console.log(obox1);
// 原生设置
// obox1.style.background = "yellow"
// 不能直接使用jq方法
// obox1.css("background","pink");
// 转换成jq之后才能使用jq方法
$(obox1).css("background","pink");
jQuery的DOM操作
选择器
封装成了css的写法
jQuery为后代选择器提供了一个方法find()这个find方法里面有一个参数,就是想要找到的后代(可以是标签,类名,ID)
$('div p').css('color','red') == $('div').find('p').css('color','red')
jQuery为子选择器提供了一个方法,children(),参数同上;
$('div>p').css('color','red') == $('div').children('p').css('color','red');
jQuery提供了next(), nextAll( ) 选择器,参数同上:注意next()选择器,只选择后一个元素。
$('div+p').css('color','red') == $('div').next('p').css('color','red')
$('div~p').css('color','red') == $('div').nextAll('p').css('color','red')
注意:children() , next() , nextAll() 这些方法如果不传递参数的话, 那么就默认传递一个通配符*,通常在使用这些选择器的时候,我们需要精准的选择元素,避免发生各种怪异结果。
检测元素是否具有指定选择器,存在为true,不存在为false
- is
- hasClass
console.log($("#msg").is("#box")); // 有为true,没有为false
console.log($("#msg").is(".red"));
console.log($("#msg").hasClass("red"));
选择自定义属性,标签名[自定义属性],选择的是所有写的标签名和有这个属性的标签,如果完整写了自定义属性的值,标签名[自定义属性=值],则选择自定义属性=值的标签
html
<div abc="hello">10</div>
<div abc="hello" qwe>11</div>
<div abc="hello" qwe="world">12</div>
<div abc="hello" qwe="hahah">13</div>
<div abc="hello" qwe="hahah" asd>14</div>
<div abc="hello" qwe="hahah" asd>15</div>
js
$("div[abc=hello]").css("background","red");
$("div[abc=hello][qwe]").css("background","red");
$("div[abc=hello][qwe=hahah]").css("background","red");
$("div[abc=hello][qwe=hahah][asd]").css("background","red");
过滤器
过滤器,也实现了选择元素的功能
- 选择器:直接选择
- 过滤器:选择范围元素之后,通过过滤得到指定元素(间接选择)
- 过滤器比选择器性能要好,所以优先选择过滤器
// 选择器
$(".msg h2").css("background","red")
// 过滤器
$(".msg").find("h2").css("background","red")
属性操作
- 内容操作(插入直接覆盖原有)
- 传参表示设置,不传参表示获取
- html() 可以解析html标签
- text(text) 不能解析html标签
- val(text) 表单类元素的value
- 传参表示设置,不传参表示获取
- class操作
- attr()
- 一个参数表示获取
- 两个参数表示设置
- 修改也是设置(设置原来就存在的属性)
- 要批量设置或修改将参数写成对象
- removeAttr()
- 删除,参数表示要删除的东西
- addClass() (添加class)
- addClass(‘class’); // 给元素添加一个class
- addClass(‘class1 class2 class3’); // 给元素添加多个class
- toggleClass(‘class’)
- 如果元素没有当前class则添加,如果有则删除,就是两种不同的状态,每次都只执行一种,下一次就换成另外一种状态,这样循环替换执行,这样的效果可以实现同一个按钮实现两个不同的功能
- attr()
html
<div id="test" class="test01"></div>
js
// 获取
console.log($("#test").attr("id"));
console.log($("#test").attr("class"));
// 设置
$(".test01").attr("test01","test01");
// 批量设置
$("#test").attr({
"test03":"test03",
"test04":"test04",
"test05":"test05",
});
// 修改
$(".test01").attr("class","test03");
// 删除
$(".test03").removeAttr("test05");
样式操作
- css()
- 一个参数表示获取
- 批量获取参数用数组
- 两个参数表示设计
- 修改也是设置(设置原来就存在的属性)
- 批量设置参数用对象
- 删除是根据对应的css设置清空
html
<div class="box" style="width:100px;height:100px;border:solid 1px black;">这是文字</div>
js
// 获取行内样式
console.log($("#test").css("width"));
// 批量获取行内样式,用数组
console.log($("#test").css(["width","height","border"]));
// 设置行内样式
$("#test").css("background", "blue");
// 批量设置行内样式,用对象
$("#test").css({
"font-size":"30px",
"color":"red"
});
// 样式的删除是根据对应的css设置清空
$("#test").css("font-size","");
$("#test").css("background","none");
快速获取尺寸类方法
-
width()
- 内容宽度width
-
innerWidth()
- width+pading
-
outerWidth()
- width+padding+border
-
offset()
- 获取某个元素相对于浏览器窗口(可视区域的距离)(相对于包含块的偏移的位置)
-
scrollTop()
- 获取垂直滚动条的值
-
以上方法,不传参表示获取,传参表示设置,有width就有height
-
position()
- 获取某个元素相对于父元素的偏移距离
html
<div id="box">
一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本一些文本
</div>
css
body{
margin: 0px;
padding: 0px;
}
#box{
position: relative;
overflow: auto;
width: 100px;
height: 100px;
border: 1px solid black;
margin: 10px;
padding: 20px;
left: 50px;
top: 100px;
}
js
// width
console.log($("#box").width());
// 传值设置
console.log($("#box").width(300));
console.log($("#box").width());
// width+pading
console.log($("#box").innerWidth());
// width+padding+border
console.log($("#box").outerWidth());
// 获取某个元素相对于浏览器窗口(可视区域的距离)(相对于包含块的偏移的位置)
console.log($("#box").offset());
// 获取垂直滚动条的值
document.onclick=function(){
console.log($("#box").scrollTop());
}
// 获取某个元素相对于父元素的偏移距离
console.log($("#box").position());
元素操作
- 创建jq的DOM对象
- $(“元素”)
- 插入到指定父元素的最后一个子
- 父.append(“子”)
- 将子元素插入到父元素
- 子.appendTo(“父”)
- 插入到指定父元素的第一个子
- 父.prepend(“子”)
- 将子插入到父元素的第一个子
- 子.prependTo(“父”)
- 插入到指定元素之前
- 指定元素.before(“元素”)
- 插入到指定元素之后
- 指定元素.after(“元素”)
- 删除自身,包括所有子
- 父.remove()
- 删除所有子
- 父.empty()
- 改元素(了解)
- 要修改的元素.replaceWith(“新元素”)
- 克隆,类似于创建元素,需要插入到指定位置(clone(true) 参数为空时,只复制元素和内容,不复制事件。为 true 时,也拷贝事件)
- 要克隆的元素.clone()(只复制元素和内容)
- 要克隆的元素.clone(true)(复制元素和内容和事件,复制的事件是和原事件是同一事件)
html
<div class="box">
<p>段落</p>
</div>
<input type="button" value="按钮" class="btn">
js
// 创建jq的DOM对象
const span = $("<span>");
const span = $("<span>这是span的文字</span>");
const span = $("<span>").html("span的文字");
// 插入到指定父元素的最后一个子
// 选择父元素,插入子元素
$(".box").append(span);
// 将子元素插入到父元素
span.appendTo($(".box"))
// 插入到指定父元素的第一个子
$(".box").prepend(span);
span.prependTo($(".box"));
// 插入到指定元素之前
$(".box").before(span);
// 插入到指定元素之后
$(".box").after(span);
// 删除自身,包括所有子
$(".box").remove();
// 删除所有子
$(".box").empty();
// 改元素(了解)
$(".box").replaceWith("<span class='"+$(".box").attr("class")+"'>"+ $(".box").html() +"</span>");
// jq的事件绑定
$(".btn").click(function(){
console.log(1);
})
// 克隆,类似于创建元素,需要插入到指定位置
$(".btn").clone(true).appendTo($("body"));
jQuery事件
事件绑定
- jq的所有事件绑定都是DOM2级,都是可以重复绑定,小心使用
- 绑定方式:
- 常规绑定:事件类型作为方法名( 常规绑定,只能绑定,不能删除)
- 支持大部分的事件
- bind绑定,unbind删除(新版中已被废弃,全面被on/off方法取代,因为on直接支持事件委托)
- on绑定,off删除
- on绑定可以直接实现事件委托
- on(事件,要委托的子元素选择器,事件处理函数)
- one绑定一次性事件(只能触发一次的事件)
- hover绑定:进入和离开
- trigger(模拟事件触发)和triggerHandler(自定执行指定事件)
- trigger默认触发事件冒泡
- triggerHandler不会触发事件冒泡
- 常规绑定:事件类型作为方法名( 常规绑定,只能绑定,不能删除)
事件对象
-
event.target 获取绑定事件的DOM元素
-
event.type 获取事件的类型
-
event.data 获取事件中传递的数据
-
event.pageX/pageY 获取根据页面原点的X,Y值
-
event.screenX/screenY 获取根据显示器窗口的X,Y值
-
event.offsetX/offsetY 获取根据父元素X,Y值
-
event.which 获取当前鼠标点击的键1,2,3
-
event.altKey/shiftKey/ctrlKey/ 返回 true、false
-
event.preventDefault() 阻止默认行为
-
event.stopPropagation() 取消事件冒泡
-
return false 阻止默认事件和事件冒泡,双层阻止,小心使用
jQuery动画
内置动画
- 被jq提前封装好了的动画效果,不能做出大范围的修改
- 显示和隐藏
- show()(显示)
- hide()(隐藏)
- toggle()(显示/隐藏)
- 滑动
- slideUp():向上滑动(隐藏)
- slideDown():向下滑动(显示)
- slideToggle():滑动(显示/隐藏)
- 淡入淡出
- fadeOut():淡出(隐藏)
- fadeIn():淡入(显示)
- fadeToggle():(显示/隐藏)
- 显示和隐藏
自定义动画
- 被jq提前半封装好了的动画方法
- animate()方法有三个参数。分别是动画目标(target),动画执行时间,回调函数。只有第一个参数是必填参数
动画的执行顺序
- 动画方法和其他方法之间是异步执行
- 借助回调函数,可以实现动画方法和其他方法之间的同步调用
- 定时器异步
- 实现链式动画
- 1.借助回调函数
- 绝对同步
- 每次动画可以控制不同元素
- 2.链式调用
- 绝对同步
- 只能控制同一个元素
- 3.多次分开添加动画
- 多次给一个元素添加:动画之间是同步执行
- 多次给不同元素添加:动画之间是异步执行
- 4.利用jq提供的添加回调函数的方法:queue
- queue的主要功能:给没有回调函数的方法,添加回调函数
- 等同于回调函数
- queue方法之后,默认无法继续链式调用,如需继续,需要在queue的回调函数身上接收一个参数,并作为函数执行,才能在queue后继续链式调用
- 1.借助回调函数
动画的控制
- 延迟:delay()
- 停止:stop()
- 参数1:队列动画:等待中的动画
- true:清除队列
- false:不清除队列,默认值
- 参数2:当前动画:正在执行的动画
- true:立即运动到终点
- false:立即停止,默认值
- 参数1:队列动画:等待中的动画
jQuery的应用
1.三级菜单
2.手风琴
3.楼层跳转
对象的链式调用(jq的特点)
将要链式调用的函数作为当前函数返回的对象
$(".box").ccc().bbb().aaa().bbb().ccc().bbb();
function $(a){
console.log(a);
return {
aaa:function(){
console.log("aaa");
console.log(this)
return this;
},
bbb:function(){
console.log("bbb");
return this;
},
ccc:function(){
console.log("ccc");
return this;
}
}
}
jQuery的ajax
- $.getJSON()
- $.getScript()
- $().load()
- 功能:请求公共的html数据,并填充到指定容器
- 注意:
- 在公共的html数据内,可以写css,但是不要写js
- 为了保证代码安全,js一定要在请求成功之后的回调函数内添加
- 如果只是给将来请求到的页面结构添加事件,也可以使用事件委托
- $.get()
- 只能实现get请求
- 注意第四个参数,最好保持默认"text"
- $.post()
- 只能实现post请求
- $.ajax()
- 通过不同的属性配置,可以实现以上所有的请求方式
jQuery的工具类方法
- ajax的全局配置
- $.ajaxSetup(ops)
- 对象的序列化
- $.param(obj)
- 表单序列化
- $(‘form’).serialize()
- 合并对象
- $.extend();
- 两个对象参数,将参数2合并到参数1
- 一个对象参数,将参数合并到jq对象
- 遍历对象
- $.each(obj, callback)
jQuery的插件
jq插件:对jq的扩展,在jq的基础之上,封装出的新功能
- 表单验证:jQuery validate
- cookie插件:jQuery cookie
- 分页插件:jQuery pageAction
开发jQuery插件
jq插件的开发规范
- 基于jq
- 插件文件命名:jquery.xxx.js
- 文件开头注意加;号,保证在合并文件时,不被其他非严格模式代码所影响
- 避免插件内部使用$,如果要使用,请传递 jQuery 进去
- 私有化全局变量
- 利用作用域,单独保存变量的功能,私有化jq的全局变量:$
- 将插件功能绑定到jq对象(jq对象,jq的DOM对象)
- 全局:$.xxx()
- 没有操作到DOM的插件,绑定到全局
- $.extend({xxx:function(){})
- $.xxx = function(){}
- DOM方法:$().xxx()
- 操作到DOM的插件,绑定到DOM
- jq的大DOM对象(DOM原型)
- $.fn
- . e x t e n d ( .extend( .extend(.fn, {xxx:function(){}})
- $.fn.extend({xxx:function(){}})
- $.fn.xxx = function(){}
- 全局:$.xxx()
;(function($){
"use strict";
// console.log($);
// 不需要操作DOM的功能
// $.xxx = function(){
// console.log("自定义的方法1")
// }
// $.extend({
// xxx:function(){
// console.log("自定义的方法2")
// }
// })
// 需要操作DOM的功能
// $.fn.xxx = function(){
// console.log("自定义的方法3")
// }
// $.fn.extend({
// xxx:function(){
// console.log("自定义的方法4")
// }
// })
// $.extend($.fn, {
// xxx:function(){
// console.log("自定义的方法5")
// }
// })
})(jQuery);
插件的功能规划
- 轮播图插件
- 需要操作DOM,所以绑定到DOM对象$.fn身上
- 请求图片数据
- 根据图片数据渲染轮播图的基本结构
- 左右按钮控制轮播图
- 分页器控制轮播图
- 自动播放
;(function($){
"use strict";
$.fn.banner = function(data, ops={}){
// 1. 处理参数
let {
btn = true, // 按钮
list = true, // 显示当前图片的列表
autoPlay = true, // 自动播放
delayTime = 3000, // 停留时间
moveTime = 300, // 切换图片时间
index = 0, // 轮播图开始的索引
currentClass = "active" // 当前的图片的高亮
} = ops;
let prev;
const that = this;
// 2. 根据数据,渲染页面结构
// 图片
init();
function init(){
let str = "";
$.each(data, (idx, val)=>{
str += `<img src="${val.src}" alt="${val.alt}" title="${val.title}">`;
})
$("<div class='imgbox'>"+str+"</div>").appendTo(that);
}
// 3. 左右按钮切换轮播图
if(btn){
$("<input type='button' id='left' value='<'>").appendTo($("<div class='btns'></div>").appendTo(this)).parent().append($("<input type='button' id='right' value='>'>")).children("#left").click(leftClick).end().children("#right").click(rightClick)
}
function leftClick(){
if(index === 0){
index = data.length-1;
prev = 0;
}else{
index--;
prev = index+1;
}
move(prev,index,-1)
}
function rightClick(){
if(index === data.length-1){
index = 0;
prev = data.length-1;
}else{
index++;
prev = index-1;
}
move(prev,index,1)
}
// 4. 分页器切换轮播图
if(list){
// 渲染页面结构并绑定事件
let str = "";
$.each(data, idx => {
str += `<span></span>`;
});
$("<div class='list'>"+str+"</div>").appendTo(this).children("span").eq(index).addClass(currentClass).end().click(function(){
if($(this).index() > index){
// console.log("左")
move(index, $(this).index(), 1)
}
if($(this).index() < index){
// console.log("右")
move(index, $(this).index(), -1)
}
// 当前点击的,就是下一次要走的
index = $(this).index();
})
}
// 5. 自动播放
if(autoPlay){
let t = setInterval(() => {
rightClick()
}, delayTime);
this.hover(function(){
clearInterval(t)
},function(){
t = setInterval(() => {
rightClick()
}, delayTime);
})
}
function move(prev,next,d){
// 先设置要走的图片的默认位置
// 开始走
// 再设置要进来的图片的默认位置
// 开始进来
that.children(".imgbox").children().eq(prev).css({
left: 0
}).stop().animate({
left: -that.children(".imgbox").children().eq(0).width() * d
}, moveTime).end().eq(next).css({
left: that.children(".imgbox").children().eq(0).width() * d
}).stop().animate({
left: 0
}, moveTime)
that.children(".list").children("span").eq(next).addClass(currentClass).siblings().removeClass(currentClass)
}
}
})(jQuery);
调用
$(".banner1").banner(imgs,{
btn:false,
list:false,
moveTime:200,
delayTime:2000
});
$(".banner2").banner(imgs);