jQuery
一、前言
1、作用
1、消除浏览器的差异:你不需要自己写冗长的代码来针对不同的浏览器来绑定事件,编写AJAX等代码;
2、简洁的操作DOM的方法:写$('#test')
肯定比document.getElementById('test')
来得简洁;
3、轻松实现动画、修改CSS等各种操作。
2、版本
目前jQuery有1.x和2.x两个主要版本,区别在于2.x移除了对古老的IE 6、7、8的支持,因此2.x的代码更精简。选择哪个版本主要取决于你是否想支持IE 6~8。
3、使用jQuery
// 在页面的<head>引入jQuery文件
<head>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
...
</head>
4、$符号
- jQuery将所有的功能全部封装在一个全局变量jQuery中,而且$是变量jQuery的别名。
- $本质上就是一个函数 jQuery(selector, context),但是不一定是这个函数名,可以进行改名。
window.$; //jQuery(selector,context)
typeof($) // function
如果$
这个变量不幸地被占用了,而且还不能改,那我们就只能让jQuery
把$
变量交出来,然后就只能使用jQuery
这个变量:
// 在占用$之前,先在内部保存了原来的$,调用jQuery.noConflict()时会把原来保存的变量还原
jQuery.noConflict();
$ // undefined
jQuery; // jQuery(selector, context)
二、选择器–获取DOM节点,拿到jQuery对象
1、基本选择器
- 作用:帮助我们快速定位到一个或多个DOM节点,不需要DOM中繁琐的定位和遍历。
- jQuery对象:使用jQuery定位DOM元素,返回的是一个jQuery对象。这个对象类似一个数组,每个元素都是一个引用了DOM节点的对象。
(1)按照ID进行查找
// 查找<div id="abc">:
// DOM的做法,a是DOM对象
var a = dcument.getElementById('abc');
// jQuery做法,div是jQuery对象
var div = $('#abc');
// 存在 [<div id='abc'>……</div>]
// 可以取第一个DOM元素,此时这个DOM对象
var divDOM = div.get(0);
// 可以将DOM对象转换成jQuery对象
var another = $(divDOM);
(2)按照tag查找
// 返回所有的<p>节点
var ps = $('p');
// 可以检查长度
ps.length;
(3)按照class查找
// 所有节点包含`class="red"`都将返回
var a = $('.red');
// <div class="red">...</div>
// <p class="green red">...</p>
// 查找同时包含red和green的节点
var a = $('.red.green');
(4)按照属性查找
一个DOM节点除了id
和class
外还可以有很多属性,很多时候按属性查找会非常方便
// 只关注属性,当属性的值包含空格等特殊字符时,需要用双引号括起来。
var email = $('[name=email]'); // 找出<??? name="email">
// 还可以按照前缀和后缀进行查找-- 正则表达式
// 找出所有name属性值以icon开头的DOM
var icons = $('[name ^= icon]')
(5)组合查找
将上面的不同的方法进行组合,从而更加精确的确定一个DOM。
// 只查找input里的属性,不查找div里面的
var emailInput = $('input[name=email]');
// 找出<tr class="red ...">...</tr>
var tr = $('tr.red');
(6)多项选择器
同时进行多个不同的DOM的选择
// 多项选择器就是把多个选择器用,组合起来一块选
把<p>和<div>都选出来
$('p,div');
2、层级选择器 $(‘ancestor descendant’)
因为DOM的结构就是层级结构,所以我们经常要根据层级关系进行选择。首先要定位父节点,才能选择相应的子节点,这样避免了页面其他不相关的元素。
<!-- HTML结构 -->
<div class="testing">
<ul class="lang">
<li class="lang-javascript">JavaScript</li>
<li class="lang-python">Python</li>
<li class="lang-lua">Lua</li>
</ul>
</div>
// 层级选择器适用于直属的父子关系也可以是祖先关系
// 以下两种写法返回一样的结果
$('ul.lang li.lang-javascript');
$('div.testing li.lang-javascript)
3、子选择器 $(‘parent > child’)
与层级选择器的区别:
子选择器$('parent>child')
类似层级选择器,但是限定了层级关系必须是父子关系,就是<child>
节点必须是<parent>
节点的直属子节点。
// 可以选出
$('ul.lang > li.lang-javascript');
// 祖先关系不可选
$('div.testing > li.lang-javascript');
4、表单元素的特殊选择器
5、过滤器 Filter
(1) filter() 方法
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Lua
var js = langs.filter('.lang-javascript') // 拿到JavaScript
(2) 伪类 + first()、
last()和
slice()
通过类似伪类的方法选择出特定位置的DOM节点。比如第一个节点,最后一个节点,序号为偶数奇数的节点。
// 选出JavaScript、Python和Lua 3个节点
var langs = $('ul.lang li');
// 仅选出JavaScript
var js = langs.first();
$('ul.lang li:first-child');
// 选出序号为奇数的元素
$('ul.lang li:nth-child(odd)');
6、查找
// 从上往下找 -- find()
var ul = $('ul.lang'); // 获得<ul>
var js = ul.find('.lang-javascript'); // 获得JavaScript
// 从下往上找 -- parent()
var js = $('li.lang-javascript'); // 获得JavaScript
var parent = js.parent(); // 获得<ul>
// 同级查找 -- next() prev()
var js = $('li.lang-javascript'); // 获得JavaScript
var py = js.next(); // python
三、操作DOM–使用jQuery对象统一之前的DOM操作
回顾一下修改DOM的CSS、文本、设置HTML有多么麻烦,而且有的浏览器只有innerHTML,有的浏览器支持innerText,有了jQuery对象,不需要考虑浏览器差异了,全部统一操作!
<div id="test-div">
<ul id="test-ul">
<li class="js">JavaScript</li>
<li name="book">Java & JavaScript</li>
</ul>
</div>
1、修改文本和添加节点 – text()、html()、append()、after()
// 通过text()和html() 获得节点的文本以及原始HTML文本
$('#test-ul li[name=book]').text(); // 'Java & JavaScript'
$('#test-ul li[name=book]').html(); // 'Java & JavaScript'
// 通过往方法里面传参进行修改节点的内容
$('#test-ul li.js').text('python');
// 一个jQuery对象可以包含多个DOM对象,所以可以一次性作用在一组DOM节点上
$('#test-ul li').text(js);
// 即便这个节点不存在,也不会报错。所以不用if判断
//除了接受字符串,append()还可以传入原始的DOM对象,jQuery对象和函数对象
var ul = $('#test-div>ul');
ul.append('<li><span>Haskell</span></li>'); //添加字符串
ul.append($('#scheme'));
// 同级节点可以用after()或者before()方法
// 在JavaScript后面插入节点
var js = $('#test-div>ul>li:first-child');
js.after('<li><span>Haskell</span></li>');
2、删除节点
var li = $('#test-div>ul>li');
li.remove(); // 所有<li>全被删除
3、修改css --css(‘name’,‘value’)
(1) 作用于style属性
// 使用css('name','value')进行设置.不传value的时候就是获取,传参的时候就是修改
var div = $('#test-div');
div.css('color'); // '#000033', 获取CSS属性
div.css('color', '#336699'); // 设置CSS属性
div.css('color', ''); // 清除CSS属性
(2) 作用于class属性
<style>
.highlight {
color: #dd1144;
background-color: #ffd351;
}
</style>
div.hasClass('highlight'); // false, class是否包含highlight
div.addClass('highlight'); // 添加highlight这个class
div.removeClass('highlight'); // 删除highlight这个class
4、显示和隐藏DOM – show()和
hide()
var a = $('a[target=_blank]');
a.hide();
a.show();
5、获取DOM节点的宽高信息
不论是节点,浏览器也可以。
// 浏览器可视化窗口
$(window).width();
// HTML文档大小
$(document).width()
// 某个节点的大小
div.weith()
6、修改DOM属性-- attr()和
removeAttr()
// 改变属性attr(),不传参就是获取,传参就是修改
div.attr('name','hello'); // div的name属性变为'Hello'
// 删除属性removeAttr()
div.removeAttr('name'); // 删除name属性
7、操作表单 – val()
/*
<input id="test-input" name="email" value="test">
<select id="test-select" name="city">
<option value="BJ" selected>Beijing</option>
<option value="SH">Shanghai</option>
<option value="SZ">Shenzhen</option>
</select>
<textarea id="test-textarea">Hello</textarea>
*/
// 对于表单元素,jQuery对象统一提供val()方法获取和设置对应的value属性
var
input = $('#test-input'),
select = $('#test-select'),
textarea = $('#test-textarea');
input.val(); // 'test'
input.val('abc@example.com'); // 文本框的内容已变为abc@example.com
// 得到是已经被用户选择的对应的value值 -- selected
select.val(); // 'BJ'
select.val('SH'); // 选择框已变为Shanghai
// 对于文本框内容就是显示的内容
textarea.val(); // 'Hello'
textarea.val('Hi'); // 文本区域已更新为'Hi'
四、事件
由于不同的浏览器绑定事件的代码都不太一样,所以用jQuery来写代码,就屏蔽了不同浏览器的差异,我们总是编写相同的代码。
1、事件绑定
(1) 常用简写方法
// 使用on()进行绑定事件
<a id="test-link" href="#0">点我试试</a>
var a = $('#test-link');
a.on('click',function(){
alert('Hello!');
});
// 直接使用click()进行事件绑定 -- 常用方法
a.click(function(){
alert('Hello!');
})
(2) 初始化DOM – ready事件
- ready:当页面被载入并且DOM树完成初始化后触发。
问题:以下代码不会达到预期,是因为JavaScript在此执行的时候,<form>
尚未载入浏览器,所以$('#testForm)
返回[]
,并没有绑定事件到任何DOM上。DOM绑定事件的代码写在了DOM节点之前。
<html>
<head>
<script>
// 代码有误:
$('#testForm').on('submit', function () {
alert('submit!');
});
</script>
</head>
<body>
<form id="testForm">
...
</form>
</body>
解决方法:自己的初始化代码必须放到document
对象的ready
事件中,保证DOM已完成初始化
<script>
$(document).on('ready',function(){
$('#testForm').on('submit', function () {
alert('submit!');
});
});
</script>
// ready事件常见写法
$(function(){
// init……
});
2、事件参数
有些事件,如mousemove
和keypress
,我们需要获取鼠标位置和按键的值,否则监听这些事件就没什么意义了。所有事件都会传入Event
对象作为参数,可以从Event
对象上获取到更多的信息
$(function () {
// 向函数中传入参数e
$('#testMouseMoveDiv').mousemove(function (e) {
$('#testMouseMoveSpan').text('pageX = ' + e.pageX + ', pageY = ' + e.pageY);
});
});
3、取消绑定 – off(‘click’,function)
function hello(){
alert('hello');
}
//绑定事件
a.click(hello);
// 不能用下面的写法绑定事件,因为off无法移除已绑定的第一个匿名函数
a.click(function(){
alert('hello');
});
// 取消绑定
a.off('click',hello);
4、事件触发条件 – 代码触发change()
事件的触发总是由用户操作引发的,但是,如果用JavaScript代码去改动文本框的值,将不会触发.
var input = $('#test-input');
input.val('change it!');
input.change(); // 触发change()事件
五、动画
实现原理:以固定的时间间隔去改变DOM的css样式即可。
1、show / hide / toggle – 从左上角逐渐展开或收缩
虽然这两个方法一开始是用来显示和隐藏DOM元素的。但是,传入时间参数,就变成了动画。
var div = $('#test-show-hide');
div.hide(3000); // 传入时间参数 -- 在3秒中内逐渐消失
div.show('slow'); // 传入字符串 -- 在0.6秒内逐渐显示
// toggle()方法则根据当前状态决定是show()还是hide()
div.toggle('slow');
2、slideUp / slideDown /slideToggle – 在垂直方向逐渐展开或收缩
div.slideUp(3000); // 传入时间参数 -- 在3秒钟内逐渐向上消失
3、fadeIn / fadeOut / fadeToggle – 淡入淡出
div.fadeOut('slow'); // 在0.6秒内淡出
4、自定义动画 – animate()
传入的参数就是DOM元素最终的CSS状态和时间,还可以再传入一个函数,当动画结束时,该函数将被调用。
var div = $('#test-animate');
// 自定义动画
div.animate({
opacity: 0.25,
width: '256px',
height: '256px'
}, 3000, function () {
console.log('动画已结束');
// 恢复至初始状态:
$(this).css('opacity', '1.0').css('width', '128px').css('height', '128px');
});
5、串行动画 – 实现复杂的连续动画
// 动画效果:slideDown - 暂停 - 放大 - 暂停 - 缩小
div.slideDown(2000)
// 暂停
.delay(1000)
.animate({
width: '256px',
height: '256px'
}, 2000)
.delay(1000)
.animate({
width: '128px',
height: '128px'
}, 2000);
}
六、AJAX
jQuery的AJAX完全封装的是JavaScript的AJAX操作,从而简化相应的操作。
1、ajax(url, settings) – 通用的发送AJAX的请求
- jQuery在全局对象
jQuery
(也就是$
)绑定了ajax()
函数,可以处理AJAX请求。函数接受一个服务器的地址,以及一个可选的settings
对象。 - settings对象的选项:
// 发送一个GET请求,并返回一个JSON格式的数据
var jqxhr = $.ajax('/api/categories',{dataType:'json'});
用回调函数处理返回的数据和出错时的响应 – 类似Promise的链式操作
2、get()、post()
- 封装的是GET请求,当传入发送的数据data的时候,data将被转换成query附加到URL上。
- 封装的是POST请求,当传入发送的数据data的时候,根据contentType把data序列化成合适的格式。
(1)$.get(URL,callback); – 从服务器中请求数据
第二个参数是回调函数。第一个回调参数存有被请求页面的内容,第二个回调参数存有请求的状态。
// 使用 $.get() 方法从服务器上的一个文件中取回数据
$('button').click(function(){[
$.get('demo.php',function(data,status){
alert('数据' + data + '\n状态' + status);
})
]})
(2) $.post(URL,data,callback); – 向服务器提交数据。
$("button").click(function(){
$.post("/try/ajax/demo_test_post.php",
// c
{
name:"菜鸟教程",
url:"http://www.runoob.com"
},
function(data,status){
alert("数据: \n" + data + "\n状态: " + status);
});
});
3、getJSON
通过GET获取一个JSON对象
// 使用类似Promise对象的方法去处理回调
var jqxhr = $.getJSON('/path/to/resource', {
name: 'Bob Lee',
check: 1
}).done(function (data) {
// data已经被解析为JSON对象了
});
4、安全限制
-
问题:安全限制同用JavaScript写AJAX,无法进行跨域请求。
-
解决方案:如果需要使用JSONP,可以在
ajax()
中设置jsonp: 'callback'
,让jQuery实现JSONP跨域加载数据。 也可以使用CORS进行处理。
七、编写jQuery插件
给jQuery对象绑定一个新方法是通过扩展$.fn
对象实现的.
<!-- HTML结构 -->
<div id="test-highlight">
<p>如何编写<span>jQuery</span> <span>Plugin</span></p>
<p>编写<span>jQuery</span> <span>Plugin</span>,要设置<span>默认值</span>,并允许用户修改<span>默认值</span>,或者运行时传入<span>其他值</span>。</p>
</div>
编写jQuery插件:高亮
// 1、给$.fn绑定函数,实现插件的代码逻辑;option参数是可以把自定义的参数传入的。
$fn.highlight = function(options){
// 合并默认值以及用户设定值
var opts = $.extend({},$.fn.highlight.defaults,options);
this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
// 2、插件函数最后要return this;以支持链式调用
return this;
}
// 用户设置默认值。3、插件函数要有默认值,绑定在$.fn.<pluginName>.defaults上
$.fn.highlight.defaults.color = '#fff';
$.fn.highlight.defaults.backgroundColor = '#000';
// 调用
// 不传参,使用用户设置的默认值
$('#test-highlight p:first-child span').highlight();
// 传参。4、用户在调用时可传入设定值以便覆盖默认值。
$('#test-highlight p:last-child span').highlight({
color: '#dd1144'
});
``
编写jQuery插件:高亮
```js
// 1、给$.fn绑定函数,实现插件的代码逻辑;option参数是可以把自定义的参数传入的。
$fn.highlight = function(options){
// 合并默认值以及用户设定值
var opts = $.extend({},$.fn.highlight.defaults,options);
this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
// 2、插件函数最后要return this;以支持链式调用
return this;
}
// 用户设置默认值。3、插件函数要有默认值,绑定在$.fn.<pluginName>.defaults上
$.fn.highlight.defaults.color = '#fff';
$.fn.highlight.defaults.backgroundColor = '#000';
// 调用
// 不传参,使用用户设置的默认值
$('#test-highlight p:first-child span').highlight();
// 传参。4、用户在调用时可传入设定值以便覆盖默认值。
$('#test-highlight p:last-child span').highlight({
color: '#dd1144'
});