# jQuery 基本概念

学习目标:学会如何使用 jQuery,掌握 jQuery 的常用 api,能够使用 jQuery 实现常见的效果。

# 为什么要学习 jQuery?

【01 - 让 div 显示与设置内容.html】

使用 javascript 开发过程中,有许多的缺点:

1. 查找元素的方法太少,麻烦。
2. 遍历伪数组很麻烦,通常要嵌套一大堆的for循环。
3. 有兼容性问题。
4. 想要实现简单的动画效果,也很麻烦
5. 代码冗余。
# jQuery 初体验

优点总结:

1. 查找元素的方法多种多样,非常灵活
2. 拥有隐式迭代特性,因此不再需要手写for循环了。
3. 完全没有兼容性问题。
4. 实现动画非常简单,而且功能更加的强大。
5. 代码简单、粗暴。
# 什么是 jQuery?

jQuery 的官网 http://jquery.com/
jQuery 就是一个 js 库,使用 jQuery 的话,会比使用 JavaScript 更简单。

js 库:把一些常用到的方法写到一个单独的 js 文件,使用的时候直接去引用这 js 文件就可以了。(animate.js、common.js)

我们知道了,jQuery 其实就是一个 js 文件,里面封装了一大堆的方法方便我们的开发,其实就是一个加强版的 common.js,因此我们学习 jQuery,其实就是学习 jQuery 这个 js 文件中封装的一大堆方法。

# jQuery 的版本

官网下载地址:http://jquery.com/download/
jQuery 版本有很多,分为 1.x 2.x 3.x

# jQuery 的入口函数

使用 jQuery 的三个步骤:

1. 引入jQuery文件
2. 入口函数
3. 功能实现

关于 jQuery 的入口函数:

// 第一种写法
$(document).ready(function() {
	
});
// 第二种写法
$(function() {
	
});

jQuery 入口函数与 js 入口函数的对比

1.	JavaScript的入口函数要等到页面中所有资源(包括图片、文件)加载完成才开始执行。
2.	jQuery的入口函数只会等待文档树加载完成就开始执行,并不会等待图片、文件的加载。
# jQuery 对象与 DOM 对象的区别(重点)
1. DOM对象:使用JavaScript中的方法获取页面中的元素返回的对象就是dom对象。
2. jQuery对象:jquery对象就是使用jquery的方法获取页面中的元素返回的对象就是jQuery对象。
3. jQuery对象其实就是DOM对象的包装集(包装了DOM对象的集合(伪数组))
4. DOM对象与jQuery对象的方法不能混用。

DOM 对象转换成 jQuery 对象:【联想记忆:花钱】

var $obj = $(domObj);
// $(document).ready (function (){}); 就是典型的 DOM 对象转 jQuery 对象

jQuery 对象转换成 DOM 对象:

var $li = $(“li”);
// 第一种方法(推荐使用)
$li[0]
// 第二种方法
$li.get(0)

# jQuery 框架应用

jQuery 是一个快速的、简洁的 JavaScript 框架(库),它的宗旨 “write less Do more” 即写更少的代码做更多的事情,它会封装很多 JavaScript 中常用的功能代码,提供了一个简洁的 JS 设计模式

  • 优化 HTML 文档操作(优化 DOM 操作)
  • 事件处理
  • 动画设计(动画存在 bug)
  • Ajax

要使用 JQ 我们需要引入对应的库文件做支持

<script src="js/jquery-3.5.1.min.js"></script>

# jQuery 基础语法

由三个部分组成

1、启动符:$ ,如果该符号在语言中已经作为关键字或者预留字使用,可以替换成 jQuery

2、选择器【用来选择需要操作的 JQ 元素】

3、方法【对元素进行操作】

# jQuery 选择器

$("h1")   //document.querySelectorAll()
$(".tit")

# 什么是 jQuery 选择器

jQuery 选择器是 jQuery 为我们提供的一组方法,让我们更加方便的获取到页面中的元素。注意:jQuery 选择器返回的是 jQuery 对象。

jQuery 选择器有很多,基本兼容了 CSS1 到 CSS3 所有的选择器,并且 jQuery 还添加了很多更加复杂的选择器。【查看 jQuery 文档】

jQuery 选择器虽然很多,但是选择器之间可以相互替代,就是说获取一个元素,你会有很多种方法获取到。所以我们平时真正能用到的只是少数的最常用的选择器。

# 基本选择器

选择器选取到的是一个 jQuery 对象

名称用法描述
ID 选择器$(“#id”);获取指定 ID 的元素
类选择器$(“.class”);获取同一类 class 的元素
标签选择器$(“div”);获取同一类标签的所有元素
并集选择器$(“div,p,li”);使用逗号分隔,只要符合条件之一就可。
交集选择器$(“div.redClass”);获取 class 为 redClass 的 div 元素

总结:跟 css 的选择器用法一模一样。

# 层级选择器

名称用法描述
子代选择器$(“ul>li”);使用 > 号,获取儿子层级的元素,注意,并不会获取孙子层级的元素
后代选择器$(“ul li”);使用空格,代表后代选择器,获取 ul 下的所有 li 元素,包括孙子等

跟 CSS 的选择器一模一样。

# 过滤选择器

这类选择器都带冒号:

获取到的为数组,并且只匹配一次,成功后就停止匹配

名称用法描述
:eq(index)$(“li:eq(2)”).css(“color”, ”red”);获取到的 li 元素中,选择索引号为 2 的元素,索引号 index 从 0 开始。
:odd$(“li:odd”).css(“color”, ”red”);获取到的 li 元素中,选择索引号为奇数的元素
:even$(“li:even”).css(“color”, ”red”);获取到的 li 元素中,选择索引号为偶数的元素

【案例:隔行变色】

# 筛选选择器 (方法)

筛选选择器的功能与过滤选择器有点类似,但是用法不一样,筛选选择器主要是方法。

名称用法描述
children(selector)$(“ul”).children(“li”)相当于 $(“ul>li”),子类选择器,可以不指明 selector
find(selector)$(“ul”).find(“li”);相当于 $(“ul li”), 后代选择器,必须要指明 selector
siblings(selector)$(“#first”).siblings(“li”);查找所有兄弟节点,不包括自己本身,不指定 selector 时会包含 script 标签
parent()$(“#first”).parent();查找父亲
eq(index)$(“li”).eq(2);相当于 $(“li:eq (2)”),index 从 0 开始
next()$(“li”).next()找下一个兄弟,包含其内容,返回的是数组
prev()$(“li”).prev()找上一个兄弟,包含其内容,返回的是数组
【案例:下拉菜单】this+children+mouseenter+mouseleave
【案例:突出展示】siblings+find
【案例:手风琴】next+parent
【案例:淘宝精品】index+eq

# jQuery 事件

jQuery 事件是把 DOM 当中常用的事件进行了一个封装,成了一个方法来调用

$(".tit").click(function(){
    // 回调函数就是当你的事件触发的时候要执行的事情
})
鼠标事件键盘事件表单事件文档 / 窗口事件
clickkeypresssubmitload(窗口)
dblclickkeydownchangeresize(窗口)
mouseenterkeyupfocusscroll(窗口)
mouseleaveblurunload(窗口)
hoverready(文档)

对于不常用的事件,jQ 提供了一个 on 方法来实现绑定

$("#btn").on("click",function(){
    console.log("呵呵呵呵")
})

# jQuery 事件委托

jQuery 事件委托通过 on 方法实现

<ul class="ul1">
    <li>1</li>
    <li class="active">2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>
<script>
    $(".ul1").on("click","li.active",function(){
        console.log(new Date());
    })
</script>

# jQuery 事件移除

jQuery 使用 off 方法

$("css选择器").off("事件类型",函数名)
// 如果没有写函数名,就移除所有

# jQuery 单次事件

// 原生写法
document.querySelector("#btn").addEventListener("click",function(){
	console.log("我被点了");
	document.querySelector("#btn").removeEventListener("click",arguments.callee)
})
//jQ 写法
$("#btn").one("click",function(){
	console.log("我被点了")
})

# jQuery 动画方法

1、show () /hide () /toggle () 执行元素的显示隐藏

注意:toggle 方法有版本兼容的问题,如果要使用 toggle 简易采用 1.7.2 一下的版本

2、slideUp () /slideDown () /slideToggle () 元素执行上下滑动

3、fadeIn () /fadeOut () /fadeTo (speed,opacity) /fadeToggle () 渐隐渐显

4、animate () 自定义动画方法

$(".switch").click(function(){
    $(".box").animate({
        "width":"500px",
        "height":"500px"
    },2000,function(){
        console.log("我完了")
    })
})

# jQuery css 方法(1)

1、addClass () 在选中的元素上添加一个类

2、removeClass () 在选中的元素上删除一个类

3、toggleClass() 在选中的元素上替换一个类

4、css () 这个方法可以在获取的元素中任意添加或者获取样式

# 获取样式

var a = $(".box").css("width");

# 设置样式(hover 时传入两个函数,移入移出事件)

$(".box").hover(function(){
    $(this).css({
        width:"500px",
        height:"500px"
    })
},function(){
    $(this).css({
        width:"300px",
        height:"300px"
    })
})

# css 操作(2)

//name:需要设置的样式名称
//value:对应的样式值
css(name, value);
// 使用案例
$("#one").css("background","gray");// 将背景色修改为灰色
// 参数是一个对象,对象中包含了需要设置的样式名和样式值
css(obj);
// 使用案例
$("#one").css({
    "background":"gray",
    "width":"400px",
    "height":"200px"
});
//name: 需要获取的样式名称
css(name);
// 案例
$("div").css("background-color");

注意:获取样式操作只会返回第一个元素对应的样式值。
隐式迭代:
1. 设置操作的时候,如果是多个元素,那么给所有的元素设置相同的值
2. 获取操作的时候,如果是多个元素,那么只会返回第一个元素的值。

# class 操作(2)

//name:需要添加的样式类名,注意参数不要带点.
addClass(name);
// 例子,给所有的 div 添加 one 的样式。
$(“div”).addClass(“one”);
//name: 需要移除的样式类名
removeClass(“name”);
// 例子,移除 div 中 one 的样式类名
$(“div”).removeClass(“one”);
//name: 用于判断的样式类名,返回值为 true false
hasClass(name)
// 例子,判断第一个 div 是否有 one 的样式类
$(“div”).hasClass(“one”);
//name: 需要切换的样式类名,如果有,移除该样式,如果没有,添加该样式。
toggleClass(name);
// 例子
$(“div”).toggleClass(“one”);

、、、
mouseenter
$("li").mouseenter(function(){
//this: 为当前的都 dom 对象, $(this) 转换为 jquery 对象

console.log($(this).text());

# jQuery 属性方法

1、html () 等价原生 DOM 中的 innerHTML 属性

$(".box").html("<h1>哈哈</h1>")  // 传参表示赋值
$(".box").html()   // 取值

2、text () 等价原生 DOM 中的 innerText 属性

3、val () 对表单的 value 属性进行操作

以上三个传参就是赋值,不传参就是取值

4、attr () 操作标签属性

$("input").attr("type");
$("input").attr("type","password")   // 注意低版本无法设置 type 属性

5、removeAttr () 移除一个属性

6、prop () 对标签的单属性进行操作

$("input").prop("checked",false)

# jQuery 的尺寸方法

1、width () /height () 获取盒子的 content 大小

2、innerWidth () /innerHeight () 获取盒子的 content+padding 的大小

3、outerWidth () /outerHeight()获取盒子的 content+padding+border 的大小

5、outerWidth (true) /outerHeight(true)获取盒子的 content+padding+border+margin 的大小

# 文档就绪函数

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/jquery-3.5.1.min.js"></script>
		<script>
			$("#btn").click(function(){
				console.log("haha")
			})
		</script>
	</head>
	<body>
		<button id="btn">按钮</button>
	</body>
</html>

代码分析:

上面的代码当中,按钮是不会有事件触发的,因为它是先绑定的事件,再加载的 DOM 元素,再绑定事件的时候 DOM 元素还没有加载出来

在原生 JS 中 window 中有一个事件 onload,它代表所有元素已经加载完毕才会触发,所以我们可以使用这个事件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/jquery-3.5.1.min.js"></script>
		<script>
			window.onload = function(){
				$("#btn").click(function(){
					console.log("haha")
				})
			}
		</script>
	</head>
	<body>
		<button id="btn">按钮</button>
	</body>
</html>

代码分析:

这些写其实不太好,因为它是将所有的元素加载完毕之后才会触发,如果一个页面上所有的元素已经加载好了,但是任然有一些大图片或者一些其他外部资源没有加载好,这个时候 onload 是不会触发的,这个从用户体验角度来讲不太好

优化一下

document.addEventListener("DOMContentLoaded",function(){
    $("#btn").click(function(){
        console.log("haha")
    })
})

代码分析:

上面的写法就更优化了,把对象改成 document,通过触发事件 DOMContentLoaded 从而不需要等待 DOM 以外的东西加载好就可以触发

而上面这套写法,在 JQ 当中有一个专门函数叫做文档就绪函数

$(document).ready(function(){
    $("#btn").click(function(){
        console.log("haha")
    })
})

进一步简化

$(function(){
    $("#btn").click(function(){
        console.log("haha")
    })
})

# Ajax 方法

jquery 封装的 Ajax 方法会自动将返回的 json 格式数据进行序列化。

我们自己封装过一套 ajax 请求,JQ 也有自己封装的

$.ajax({
	async:true,               // 是否异步,默认 false
	type:"get",               // 请求方法,默认是 get
	url:"",                   // 请求地址
	dataType:"json",          // 返回的数据类型,如果是 json 则自动反序列化
	success:function(data){   
		// 请求成功时,执行的回调,data 相当于 xhr 对象中的 response
	},
	error:function(err){
		// 请求失败时执行的回调,err 错误信息
	}
})

JQ 自己也觉得上面的写法很麻烦,所以由简化了一下

$.get(url,function(data){
})
或者
$.post(url, data, function(response) {
  // 处理响应数据
});
$.extend  === Array.prototype.abc

ajax 的封装方法中有 xhr 对象,此对象指向自己,施一公 xhr.upload.onprogress 方法创建一个函数,可以生成进度条样式(通过 e.loaded 和 e.total,函数事件中内置的属性)

$.extend  === Array.prototype.abc

# JQuery 的其他方法

1、 each() 方法

$(".ul1>li").each(function(index,ele){
    console.log(index,ele);
})

选取元素之后,可以直接进行遍历,回调函数里面的第一个参数代表索引,第二个参数表单当前遍历的元素

var result = $(".ul1>li");
$.each(result,function(index,ele){
	console.log(index,ele);
})

上面的调用 $.each 的时候,里面的 result 是一个类数组,所以我们可以用这个方法来进行遍历

2、 toArray() 可以把 Jquery 选择操作的对象转换成一个数组

$(".ul1>li").toArray();   // 这个时候就变成了一个数组

刚刚上面的 toArray() 是可以将 JQuery 的选择结果转化昵称真正的数组,但是这个结束是不是 JQuery 选取的?

3、 makeArray() 可以将任何类数组转换成数组

var lis = document.querySeletorAll(".ul1>li")    // 得到是一个 NodeList 类型的类数组

把上面的 NodeList,我们通过已经学过的方法转成数组

第一种

var arr = Array.prototype.slice.call(lis);

第二种

var arr = $(lis).toArray();

第三种

var arr = $.makeArray(lis);

# JQuery 的扩展

on 的使用

第一种方式

$("#btn1").on("click",function(){
	console.log("单击事件")
})
$("#btn1").on("mousedown",function(){
	console.log("鼠标按下事件")
})
$("#btn1").on("mouseup",function(){
	console.log("鼠标松开事件")
})

第二种写法

$("#btn1").on({
	click: function(){
		console.log("单击事件")
	},
	mousedown: function(){
		console.log("鼠标按下事件")
	},
	mouseup: function(){
		console.log("鼠标松开事件")
	}
})

第三种:链式语法

# DOM 的 attribute 和 property

attribute:在 web 前端中指的是 HTML 的属性

property:在 web 前端中指的是对象的属性

$("#input1").attr("type");
$("#input1").prop("checked",false);

# JQuery 对象于普通 DOM 对象的转换

<body>
    <button type="button" id="btn1">按钮</button>
</body>
<script type="text/javascript">
    var btn1 = document.querySelector("#btn1");   //btn 是一个原生的 DOM 对象
    var btn2 = $("#btn1");    //JQuery 的初始化操作对象,jQuery.fn.init
</script>

首先我们要知道一点,$(选择器) 它返回的是一个 JQuery 对象,是一个类数组形式

JQuery 对象转换成 DOM

btn2[0];
$("#btn1")[0];   // 这样就得到了原生的 DOM 对象
// 接下来就可以操作对应的原生的 js 方法

普通 DOM 对象转成 JQuery 对象

$(btn1);   // 这样就得到了 JQuery 的操作对象
// 只要得到了就可以使用 JQ 方法进行操作
$(btn1).text();

# JQ 里面的事件对象

JQuery 的事件全部都是二级事件,并且它默认执行的是事件冒泡

JQuery 当中的事件对象并不是原生的事件对象,而是经过 JQuery 自己的封装的一个对象,正是因为它是自己封装的对象,所以 JQuery 事件对象肯定是与原生有一些不一样的

1、JQuery 的事件对象不需要做兼容性的处理,因为在框架内部就已经了处理了

// 原生的 DOM 事件对象
event = event || window.event;
// 而 JQuery 里面,直接使用 event 就好了

2、JQuery 事件对象上面的 stopPropagtion() 它自己封装的方法,它不是原生的事件对象的方法,所以在停止事件冒泡与取消事件传播的时候,直接调用这一个方法就行了

// 原生 DOM 的事件里面,取消事件传播与冒泡
event.cancelBubble = true//IE
event.stopPropagtion();       //W3c
// 在 JQuery 中,直接调用方法即可
event.stopPropagtion();

3、JQuery 事件对象里面,如果要阻止事件的默认行为也是 event.preventDefault() , 而在原生 DOM 对象里面,0 级使用 return false 2 级事件使用 event.preventDefault()

// 原生 DOM
//0 级事件
// 在事件方法的最后添加
return false
//JQuery 当中,直接调用
event.preventDefault()

4、JQuery 事件里面的 return false 会同时停止事件冒泡与阻止事件默认行为,相当于把 stopPropagtion()preventDefault() 都干了

5、jQuery 当中的事件对象是框架自己封装的对象,如果要找原生的事件对象可以使用 originalEvent 这个属性

6、JQuery 的事件对象中 which 属性代表鼠标的键,1 代表左键,2 代表中键,3 代表右键

7、因为 JQuery 事件是 2 级事件可以实现多次监听,这样在触发的时候会同时调用所有监听的方法,这时候会形成事件链,在 JQuery 当中提供了一个排他的特性,它是 event.stopImmediatePropagation()

$("#btn1").on("click",function(){
    console.log("我是第一次")
}).on("click",function(event){
    console.log("第二次");
    event.stopImmediatePropagation();  // 事件链到这里就断掉了,后面的事件方法不执行
}).on("click",function(){
    console.log("第三次");
})

# JQuery 事件委托拓展

在 JQ 里面事件委托和原生 DOM 里面实现的事件委托有点不一样

原生 DOM 里面

  • event.target 代表事件的触发者
  • event.currentTarget 代表事件的绑定者

JQuery 框架里面

  • event.target 代表事件的触发者
  • event.currentTarget 代表事件的绑定者
  • event.delegateTarget 代表事件的委托者
<body>
    <div class="box">
        <div class="small-box">
            <button type="button" class="btn1">按钮</button>
        </div>
    </div>
</body>
<script type="text/javascript">
    $(".box").on("click",".small-box",function(){
        console.log("我触发了事件",event);
    })
</script>

当我们点击按钮的时候,会触发 click 事件,这个时候我们来分析下这个事件对象

1、我们把事件绑定在了 box 身上,但是 box 又把事件委托给了 small-box 所以我们认为,事件现在实际上是在 small-box 身上

2、当我们点击按钮按钮的时候,会触发按钮身上的 click 事件,但是按钮本身并没有事件方法需要执行,所以按钮本身并不会又任何的事情发生,但是事件传播的行为任然是会发生的,所以按钮的点击事件传播到了外面的 small-box 身上,正好触发了 small-box 身上委托的事件方法

  • delegateTargetdiv.box
  • currentTargetdiv.small-box
  • targetbutton.btn1

总的来说,它的格式因该是如下

$(委托者).on(事件类型,事件绑定者,function(){
	// 这里面可以找到真正的 target 触发者
})

# JQuery 方法中的 this

$(".box").on("click",".small-box",function(){
    console.log(this);          //small-box
})
    
$(".box").on("click",function(){
    console.log(this);          //box
})

JQuery 里面的事件当中的 this 永远指向谁事件的绑定者 event.currentTarget

Jquery 当中的 this 的一种特殊用法,它可以直接通过选择器选取以后再操作

$(this)   // 这就相当于对当前元素选取之后再操作

# JQuery 的扩展方法

在 JQuery 当中,它为我们提供了很多的方法,同时也可以让我们自己来实现自定义的方法,这些自定义的方法,我们叫做 jQuery 的扩展方法

jQuery 的扩展方法有两种形式存在

1、 $.extend() ,这种情况直接在 $ 对象身上扩展方法

2、 $.fn.extend() ,这种情况是在 JQuery 选取的元素上面扩展方法

<div id="div1"></div>
<script type="text/javascript">
    $.extend({
        aaa:function(){
            console.log("我是JQuery对象上面扩展的aaa方法");
        }
    })
    $.aaa();
    $.fn.extend({
        bbb:function(){
            console.log("我是JQuery操作对象上面扩展的bbb方法")
        }
    })
    $("#div1").bbb();
</script>

# JQuery 扩展方法实现插件制作

index.html 部分

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<link rel="stylesheet" href="css/context-menu-box.css">
		
		<style>
			.box{
				width:400px;
				height:400px;
				border:solid 1px #f00;
			}
		</style>
	</head>
	<body>
		<div class="box">
			<!-- <ul class="context-menu-box">
				<li>haha</li>
				<li>haha</li>
				<li>haha</li>
			</ul> -->
		</div>
	</body>
	<script src="js/jquery-1.7.2.min.js" type="text/javascript"></script>
	<script src="js/jQuery.contextmenu.js"></script>
	<script type="text/javascript">
		var menuList = [
			{
				text: "退回",
				click: function(){
					console.log("你要退回么?")
				}
			},
			{
				text: "提交",
				click: function(){
					console.log("你正在提交")
				}
			},
			{
				text: "登录",
				click: function(){
					console.log("你在登录")
				}
			}
		]
		$(".box").addContextMenu(menuList);
	</script>
</html>

context-menu-box.css 部分

*{
	padding:0;
	margin:0;
}
ul,ol{
	list-style:none;
}
a{
	text-decoration: none;
	color:#333;
}
.context-menu-box{
	width:130px;
	position: fixed;
	left:0;
	top:0;
	background-color: #fff;
	box-shadow:0 0 5px #000;
	display:none;
}
.context-menu-box>li{
	line-height:35px;
	border-bottom: solid 1px #ccc;
	cursor: pointer;
	text-align: center;
}
.context-menu-box>li:hover{
	font-weight: bold;
}

jQuery.contextmenu.js

(function($){
	if(typeof $ == undefined){
		throw new Error("jQuery is not defined");
		return;
	}
	$.fn.extend({
		addContextMenu: function(menuList){
			var menuUl = document.createElement("ul");
			menuUl.classList.add("context-menu-box");
			for(var i = 0;i < menuList.length;i++){
				var newli = document.createElement("li");
				newli.innerText = menuList[i].text;
				// 判断一下是否有 click 事件
				if(typeof menuList[i].click === "function"){
					$(newli).on("click",menuList[i].click);
				}
				menuUl.appendChild(newli);
			}
			document.body.appendChild(menuUl);
			
			// 点击自己的时候,把自己隐藏掉
			$(menuUl).click(function(){
				$(this).hide();
			})
			// 绑定右键菜单事件
			this.contextmenu(function(event){
				event.preventDefault();
				var x = event.clientX;
				var y = event.clientY;
				$(menuUl).css({
					left: x + "px",
					top: y + "px"
				}).slideDown("fast");
			})
		}
	})
})(jQuery)   
/*
$ 符号并不是 jQuery 独占的一个标识符,你有可以在实际的工作中
会引入多个框架文件进行使用,有可以在其他的框架文件中也使用了 $ 这个
符号作为它自己的标识符使用,那么这个时候,两个框架文件之间就会
产生冲突,jQuery 在这个情况下,可以使用另外一个标识符来替代 $ 的作用
就是 jQuery
*/
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

dmq 微信支付

微信支付

dmq 支付宝

支付宝