Fork me on GitHub

jQuery笔记

文章概述

本篇文章记录jQuery的笔记。

参考资料

API中文在线文档

jQuery

概述

  • $是著名的jQuery符号;
  • jQuery把所有功能全部封装在一个全局变量jQuery中,而$也是一个合法的变量名,它是变量jQuery的别名。
  • jQuery(selector, context)===$;

jquery的定义相当于

1
2
3
4
window.jQuery; // jQuery(selector, context)
window.$; // jQuery(selector, context)
$ === jQuery; // true
typeof($); // 'function'

$函数名占用

如果$这个变量不幸地被占用了,而且还不能改,那我们就只能让jQuery把$变量交出来,然后就只能使用jQuery这个变量:

1
2
3
4
$; // jQuery(selector, context)
jQuery.noConflict();
$; // undefined
jQuery; // jQuery(selector, context)

选择器

概述

使用格式类似:

1
$('dom_selector')
  • 返回的对象是jQuery对象是数组[];
  • jQuery的选择器不会返回undefined或者null,这样的好处是你不必在下一行判断if (div === undefined)。

基础选择器

ID

按ID查找

1
2
3
// 查找<div id="abc">:
var div = $('#abc');
// 返回:[<div id="abc">...</div>]
tag

按tag查找

按tag查找只需要写上tag名称就可以了:

1
2
var ps = $('p'); // 返回所有<p>节点
ps.length; // 数一数页面有多少个<p>节点
class

按class查找注意在class名称前加一个.:

1
2
3
4
var a = $('.red'); // 所有节点包含`class="red"`都将返回
// 例如:
// <div class="red">...</div>
// <p class="green red">...</p>
多class节点
1
2
3
4
var a = $('.red.green'); // 注意没有空格!
// 符合条件的节点:
// <div class="red green">...</div>
// <div class="blue green red">...</div>
属性

按属性查找

一个DOM节点除了id和class外还可以有很多属性,很多时候按属性查找会非常方便,比如在一个表单中按属性来查找:

1
2
3
var email = $('[name=email]'); // 找出<??? name="email">
var passwordInput = $('[type=password]'); // 找出<??? type="password">
var a = $('[items="A B"]'); // 找出<??? items="A B">
前后缀查找
1
2
3
4
var icons = $('[name^=icon]'); // 找出所有name属性值以icon开头的DOM
// 例如: name="icon-1", name="icon-2"
var names = $('[name$=with]'); // 找出所有name属性值以with结尾的DOM
// 例如: name="startswith", name="endswith"js
class属性查找
1
2
var icons = $('[class^="icon-"]'); // 找出所有class包含至少一个以`icon-`开头的DOM
// 例如: class="icon-clock", class="abc icon-home"
组合查找
概述

可以将id、class、tag、属性等基础选择器组合起来进行查找;

实例

查找input中name是email的属性:

1
var emailInput = $('input[name=email]'); // 不会找出<div name="email">

根据tag和class来组合查找

1
var tr = $('tr.red'); // 找出<tr class="red ...">...</tr>
多项选择器
  • 选出来的元素是按照它们在HTML中出现的顺序排列的,而且不会有重复元素;
  • 多项选择器就是把多个选择器用,组合起来一块选;
1
2
$('p,div'); // 把<p>和<div>都选出来
$('p.red,p.green'); // 把<p class="red">和<p class="green">都选出来

层级选择器

概述

如果DOM元素具有层级关系,就可以用$(‘ancestor descendant’)来选择,层级之间用空格隔开.

父子层级选择
1
2
3
4
5
6
7
8
<!-- 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>
1
2
3
4
$('ul.lang li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
$('div.testing li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
$('ul.lang li');
$('form[name=upload] input');
多层选择
1
$('form.test p input'); // 在form表单选择被<p>包含的<input>
直属子选择器

child节点必须是parent节点的直属子节点

1
$('parent>child')

实例:

1
2
$('ul.lang>li.lang-javascript'); // 可以选出[<li class="lang-javascript">JavaScript</li>]
$('div.testing>li.lang-javascript'); // [], 无法选出,因为<div>和<li>不构成父子关系

伪类过滤器

过滤器一般不单独使用,它通常附加在选择器上,帮助我们更精确地定位元素。观察过滤器的效果:

一般过滤
1
2
3
4
5
6
7
8
$('ul.lang li'); // 选出JavaScript、Python和Lua 3个节点
$('ul.lang li:first-child'); // 仅选出JavaScript
$('ul.lang li:last-child'); // 仅选出Lua
$('ul.lang li:nth-child(2)'); // 选出第N个元素,N从1开始
$('ul.lang li:nth-child(even)'); // 选出序号为偶数的元素
$('ul.lang li:nth-child(odd)'); // 选出序号为奇数的元素
$('div:visible'); // 所有可见的div
$('div:hidden'); // 所有隐藏的div
表单相关

针对表单元素,jQuery还有一组特殊的选择器:

1
2
3
4
5
6
7
8
9
:input:可以选择<input>,<textarea>,<select>和<button>;
:file:可以选择<input type="file">,和input[type=file]一样;
:checkbox:可以选择复选框,和input[type=checkbox]一样;
:radio:可以选择单选框,和input[type=radio]一样;
:focus:可以选择当前输入焦点的元素,例如把光标放到一个<input>上,用$('input:focus')就可以选出;
:checked:选择当前勾上的单选框和复选框,用这个选择器可以立刻获得用户选择的项目,如$('input[type=radio]:checked');
:enabled:可以选择可以正常输入的<input>、<select>
等,也就是没有灰掉的输入;
:disabled:和:enabled正好相反,选择那些不能输入的。

查找和过滤

当我们拿到一个jQuery对象后,还可以以这个对象为基准,进行查找和过滤。

样本:

1
2
3
4
5
6
7
8
<!-- HTML结构 -->
<ul class="lang">
<li class="js dy">JavaScript</li>
<li class="dy">Python</li>
<li id="swift">Swift</li>
<li class="dy">Scheme</li>
<li name="haskell">Haskell</li>
</ul>
查找
向下查找

jquery对象的find(selector)方法;

1
2
3
4
var ul = $('ul.lang'); // 获得<ul>
var dy = ul.find('.dy'); // 获得JavaScript, Python, Scheme
var swf = ul.find('#swift'); // 获得Swift
var hsk = ul.find('[name=haskell]'); // 获得Haskell
向上查找

从当前节点开始向上查找,使用parent()方法:

1
2
3
var swf = $('#swift'); // 获得Swift
var parent = swf.parent(); // 获得Swift的上层节点<ul>
var a = swf.parent('.red'); // 获得Swift的上层节点<ul>,同时传入过滤条件。如果ul不符合条件,返回空jQuery对象
同级查找

对于位于同一层级的节点,可以通过next()查找后一个,prev()查找前一个;

1
2
3
4
5
6
7
var swift = $('#swift');

swift.next(); // Scheme
swift.next('[name=haskell]'); // 空的jQuery对象,因为Swift的下一个元素Scheme不符合条件[name=haskell]

swift.prev(); // Python
swift.prev('.dy'); // Python,因为Python同时符合过滤器条件.dy
高阶过滤

和函数式编程的map、filter类似,jQuery对象也有类似的方法。

filter
  1. 过滤掉不符合选择器条件的节点
1
2
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var a = langs.filter('.dy'); // 拿到JavaScript, Python, Scheme
  1. 传入函数,要特别注意函数内部的this被绑定为DOM对象,不是jQuery对象:
1
2
3
4
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
langs.filter(function () {
return this.innerHTML.indexOf('S') === 0; // 返回S开头的节点
}); // 拿到Swift, Scheme
map
  1. map()方法把一个jQuery对象包含的若干DOM节点进行处理:
1
2
3
4
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var arr = langs.map(function () {
return this.innerHTML;
}).get(); // 用get()拿到包含string的Array:['JavaScript', 'Python', 'Swift', 'Scheme', 'Haskell']
其他

jQuery对象包含不止一个DOM节点时,first()、last()和slice()方法可以返回一个新的jQuery对象,把不需要的DOM节点去掉:

1
2
3
4
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var js = langs.first(); // JavaScript,相当于$('ul.lang li:first-child')
var haskell = langs.last(); // Haskell, 相当于$('ul.lang li:last-child')
var sub = langs.slice(2, 4); // Swift, Scheme, 参数和数组的slice()方法一致

操作DOM

Dom对象相互转换

jQuery对象和DOM对象之间可以互相转化,通常情况下你不需要获取DOM对象,直接使用jQuery对象更加方便。如果你拿到了一个DOM对象,那可以简单地调用$(aDomObject)把它变成jQuery对象,这样就可以方便地使用jQuery的API了。

1
2
3
var div = $('#abc'); // jQuery对象
var divDom = div.get(0); // 假设存在div,获取第1个DOM元素
var another = $(divDom); // 重新把DOM包装为jQuery对象

文本

  • jQuery对象的jQuery对象的text()和html()方法分别获取节点的文本和原始HTML文本;
  • 无参数调用text()是获取文本,传入参数就变成设置文本,html()类似;
获取文本
1
2
3
4
5
6
7
8
9
<!-- HTML结构 -->
<ul id="test-ul">
<li class="js">JavaScript</li>
<li name="book">Java &amp; JavaScript</li>
</ul>
<script>
$('#test-ul li[name=book]').text(); // 'Java & JavaScript'
$('#test-ul li[name=book]').html(); // 'Java &amp; JavaScript'
</script>
修改文本
1
2
3
4
var j1 = $('#test-ul li.js');
var j2 = $('#test-ul li[name=book]');
j1.html('<span style="color: red">JavaScript</span>');
j2.text('JavaScript & ECMAScript');

css样式

概述
  • 修改css样式:调用jQuery对象的css(‘name’, ‘value’)方法;
  • 为了和JavaScript保持一致,CSS属性可以用’background-color’和’backgroundColor’两种格式;
  • Query对象的css()方法可以链式调用;
操作css

修改css:

  • 添加样式: 直接使用css(key,value)方法,可以接受一个css样式json对象,如:css({key:value,…});
  • 修改class属性:addClass()、hasClass()、removeClass();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- HTML结构 -->
<ul id="test-css">
<li class="lang dy"><span>JavaScript</span></li>
<li class="lang"><span>Java</span></li>
<li class="lang dy"><span>Python</span></li>
<li class="lang"><span>Swift</span></li>
<li class="lang dy"><span>Scheme</span></li>
</ul>
<script>
// 添加css样式
$('#test-css li.dy>span')
.css('background-color', '#ffd351')
.css('color', 'red');

// 修改css的class属性
var div = $('#test-div');
div.hasClass('highlight'); // false, class是否包含highlight
div.addClass('highlight'); // 添加highlight这个class
div.removeClass('highlight'); // 删除highlight这个class
</script>

显隐DOM

  • 要隐藏一个DOM,我们可以设置CSS的display属性为none,利用css()方法就可以实现。不过,要显示这个DOM就需要恢复原有的display属性,这就得先记下来原有的display属性到底是block还是inline还是别的值。
  • jQuery直接提供show()和hide()方法,我们不用关心它是如何修改display属性的;
  • jQuery隐藏DOM节点并未改变DOM树的结构,它只影响DOM节点的显示。这和删除DOM节点是不同的。
1
2
3
var a = $('a[target=_blank]');
a.hide(); // 隐藏
a.show(); // 显示

DOM大小

利用jQuery对象的若干方法,我们直接可以获取DOM的高宽等信息,而无需针对不同浏览器编写特定代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 浏览器可视窗口大小:
$(window).width(); // 800
$(window).height(); // 600

// HTML文档大小:
$(document).width(); // 800
$(document).height(); // 3500

// 某个div的大小:
var div = $('#test-div');
div.width(); // 600
div.height(); // 300
div.width(400); // 设置CSS属性 width: 400px,是否生效要看CSS是否有效
div.height('200px'); // 设置CSS属性 height: 200px,是否生效要看CSS是否有效

DOM属性

attr和removeAttr

attr()和removeAttr()方法用于操作DOM节点的属性:

1
2
3
4
5
6
7
// <div id="test-div" name="Test" start="1">...</div>
var div = $('#test-div');
div.attr('data'); // undefined, 属性不存在
div.attr('name'); // 'Test'
div.attr('name', 'Hello'); // div的name属性变为'Hello'
div.removeAttr('name'); // 删除name属性
div.attr('name'); // undefined
prop

prop()方法和attr()类似,但是对于选择控件返回boolean的属性(selected、checked)处理有所不同;

1
2
3
4
5
6
7
8
9
<input id="test-radio" type="radio" name="test" checked value="1">
<input id="test-radio" type="radio" name="test" checked="checked" value="1">

<script>
// 返回boolean的处理
var radio = $('#test-radio');
radio.attr('checked'); // 'checked'
radio.prop('checked'); // true
</script>
is

is()判断boolean返回值(推荐);
(selected、checked)

1
2
3
4
5
var radio = $('#test-radio');
radio.is(':checked'); // true

var checkbox =$(#test-select)
checkbox.is(':selected');
操作表单

对于表单元素,jQuery对象统一提供val()方法获取和设置对应的value属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<input id="test-input" name="email" value="">
<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>
<script>
var
input = $('#test-input'),
select = $('#test-select'),
textarea = $('#test-textarea');

input.val(); // 'test'
input.val('abc@example.com'); // 文本框的内容已变为abc@example.com

select.val(); // 'BJ'
select.val('SH'); // 选择框已变为Shanghai

textarea.val(); // 'Hello'
textarea.val('Hi'); // 文本区域已更新为'Hi'
</script>

修改DOM结构

要添加新的DOM节点,除了通过jQuery的html()这种暴力方法外,还可以用append()方法;

添加节点
append方法

append方法:append()把DOM添加到最后。

1
2
3
【注意】
如果要添加的DOM节点已经存在于HTML文档中,它会首先从文档移除,然后再添加;
也就是说,用append(),你可以移动一个DOM节点。

  • 可以传入HTML片段;
  • 可以传入原始的DOM对象;
  • 可以传入函数,但是要求返回一个字符串、DOM对象或者jQuery对象;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div id="test-div">
<ul>
<li><span>JavaScript</span></li>
<li><span>Python</span></li>
<li><span>Swift</span></li>
</ul>
</div>
<script>
var ul = $('#test-div>ul');
ul.append('<li><span>Haskell</span></li>');

// 创建DOM对象:
var ps = document.createElement('li');
ps.innerHTML = '<span>Pascal</span>';
// 添加DOM对象:
ul.append(ps);

// 添加jQuery对象:
ul.append($('#scheme'));

// 添加函数对象:
ul.append(function (index, html) {
return '<li><span>Language - ' + index + '</span></li>';
});
</script>
prepend方法

prepend()则把DOM添加到最前,用法与append类似

添加到指定位置

同级节点可以用after()或者before()方法,添加节点到指定节点元素之后或之前;

1
2
var js = $('#test-div>ul>li:first-child');
js.after('<li><span>Lua</span></li>');
删除节点

要删除DOM节点,拿到jQuery对象后直接调用remove()方法就可以了。如果jQuery对象包含若干DOM节点,实际上可以一次删除多个DOM节点:

1
2
var li = $('#test-div>ul>li');
li.remove(); // 所有<li>全被删除

遍历DOM

each

each() 方法规定为每个匹配元素规定运行的函数。

1
提示:返回 false 可用于及早停止循环。
语法
1
$(selector).each(function(index,element))

参数:function(index,element)

(必需。为每个匹配元素规定运行的函数。)

  • index - 选择器的 index 位置
  • element - 当前的元素(也可使用 “this” 选择器)

事件

绑定事件

  • 绑定事件需要在dom加载完成后进行绑定,所以需要在ready事件中进行事件绑定;
  • 详见:其他事件->ready事件。
  • 绑定事件时,绑定非匿名函数,只需要填写相应的函数名称即可,加括号则相当于直接调用了;
on方法绑定

jQuery对象的on方法绑定事件,需要传入事件名称和对应的处理函数。

1
2
3
4
5
6
7
8
9
10
11
<a id="test-link" href="#0">点我试试</a>
<script>
$(function () {
// 获取超链接的jQuery对象:
var a = $('#test-link');
// 通过on方法
a.on('click',function () {
alert('Hello!');
});
});
</script>

如果是调用外部非匿名函数,需要写入函数名称;

1
2
3
4
5
6
7
8
9
10
function hello() {
alert("world")
}

$(function () {
// 获取超链接的jQuery对象:
var a = $('#test-link');
// 通过on方法
a.click(hello);
});

直接绑定

jQuery对象可以直接绑定事件;

1
2
3
4
5
6
7
8
9
10
11
<a id="test-link" href="#0">点我试试</a>
<script>
$(function () {
// 获取超链接的jQuery对象:
var a = $('#test-link');
// 直接调用click()方法
a.click(function () {
alert('Hello!');
});
});
</script>
proxy事件函数绑定this

$.proxy 方法接受一个已有的函数,并返回一个带特定上下文的新的函数。

1
2
3
//【语法】
$(selector).proxy(function,context)
$(selector).proxy(context,fn_name)

事件分类

jQuery对象能够绑定的事件分类。

鼠标事件
  • click: 鼠标单击时触发;
  • dblclick:鼠标双击时触发;
  • mouseenter:鼠标进入时触发;
  • mouseleave:鼠标移出时触发;
  • mousemove:鼠标在DOM内部移动时触发;
  • hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。
键盘事件

键盘事件仅作用在当前焦点的DOM上,通常是input和textarea。

  • keydown:键盘按下时触发;
  • keyup:键盘松开时触发;
  • keypress:按一次键后触发。
其他事件
1
2
3
4
5
- focus:当DOM获得焦点时触发;
- blur:当DOM失去焦点时触发;
- change:当<input>、<select>或<textarea>的内容改变时触发;
- submit:当<form>提交时触发;
- ready:当页面被载入并且DOM树完成初始化后触发,仅作用于document对象。
ready事件

ready仅作用于document对象。由于ready事件在DOM完成初始化后触发,且只触发一次,所以非常适合用来写其他的初始化代码。

用法示例
  1. 简单用法;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<script>
$(document).on('ready', function () {
$('#testForm).on('submit', function () {
alert('submit!');
});
});
</script>
</head>
<body>
<form id="testForm">
...
</form>
</body>
  1. 简化写法;
1
2
3
4
5
6
$(document).ready(function () {
// on('submit', function)也可以简化:
$('#testForm).submit(function () {
alert('submit!');
});
});
  1. 最简化写法(推荐);
1
2
3
4
// document对象的ready事件处理函数
$(function () {
// init...
});

事件参数

Event对象作为参数;

有些事件,如mousemove和keypress,我们需要获取鼠标位置和按键的值,否则监听这些事件就没什么意义了。所有事件都会传入Event对象作为参数,可以从Event对象上获取到更多的信息:

1
2
3
4
5
$(function () {
$('#testMouseMoveDiv').mousemove(function (e) {
$('#testMouseMoveSpan').text('pageX = ' + e.pageX + ', pageY = ' + e.pageY);
});
});

取消绑定

off方法用于取消绑定;

  • 一个已被绑定的事件可以解除绑定,通过off(‘click’, function)实现;
  • 无参数调用off()一次性移除已绑定的所有类型的事件处理函数。
1
2
3
4
5
6
7
8
9
10
function hello() {
alert('hello!');
}

a.click(hello); // 绑定事件

// 10秒钟后解除绑定:
setTimeout(function () {
a.off('click', hello);
}, 10000);

手动触发事件

1
2
3
4
5
6
一个需要注意的问题是,事件的触发总是由用户操作引发的。

例如:
绑定文本框一个改变事件,当用户在文本框中输入时,就会触发change事件。
但是,如果用JavaScript代码去改动文本框的值,将不会触发change事件。
如果需要手动触发,则直接调用input.change()方法即可。
手动触发方式
  1. 调用input.trigger(‘change’);
  2. 直接调用jquery对象的无参事件方法(相当trigger()方法的简写)即可(推荐);
浏览器安全限制

在浏览器中,有些JavaScript代码只有在用户触发下才能执行,例如,window.open()函数:

1
2
3
4
// 无法打开新窗口,将被浏览器屏蔽:
$(function () {
window.open('/');
});

内置动画

概览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
animate()	对被选元素应用“自定义”的动画
clearQueue() 对被选元素移除所有排队的函数(仍未运行的)
delay() 对被选元素的所有排队函数(仍未运行)设置延迟
dequeue() 运行被选元素的下一个排队函数
fadeIn() 逐渐改变被选元素的不透明度,从隐藏到可见
fadeOut() 逐渐改变被选元素的不透明度,从可见到隐藏
fadeTo() 把被选元素逐渐改变至给定的不透明度
hide() 隐藏被选的元素
queue() 显示被选元素的排队函数
show() 显示被选的元素
slideDown() 通过调整高度来滑动显示被选元素
slideToggle() 对被选元素进行滑动隐藏和滑动显示的切换
slideUp() 通过调整高度来滑动隐藏被选元素
stop() 停止在被选元素上运行动画
toggle() 对被选元素进行隐藏和显示的切换

显隐动画

左上角显隐

方法:show、hide和toggle,从左上角逐渐展开或收缩的;

  • 直接以无参数形式调用show()和hide(),会显示和隐藏DOM元素。
  • 调用toggle()方法则根据当前状态决定是show()还是hide()。
  • 只要传递一个时间参数进去,就变成了动画.
  • 时间以毫秒为单位,但也可以是’slow’,’fast’这些字符串;
1
2
3
4
5
var div = $('#test-show-hide');
div.hide(3000); // 在3秒钟内逐渐消失

var div = $('#test-show-hide');
div.show('slow'); // 在0.6秒钟内逐渐显示
垂直方向显隐

slideUp()和slideDown()则是在垂直方向逐渐展开或收缩的,而slideToggle()则根据元素是否可见来决定下一步动作;

用法与show、hide类似;

1
2
var div = $('#test-slide');
div.slideUp(3000); // 在3秒钟内逐渐向上消失

淡入淡出

fadeIn()和fadeOut()的动画效果是淡入淡出,也就是通过不断设置DOM元素的opacity属性来实现,而fadeToggle()则根据元素是否可见来决定下一步动作,用法与show、hide类似。

1
2
var div = $('#test-fade');
div.fadeOut('slow'); // 在0.6秒内淡出
滑动

滑动方法可使元素上下滑动,用法类似show动画。

  • slideDown(): 向下;
  • slideUp():向上;
  • slideToggle():根据当前状态向上或向下;
1
2
3
$("#flip").click(function(){
$("#panel").slideDown();
});

自定义动画

animate(),它可以实现任意动画效果。需要传入的参数就是DOM元素最终的CSS状态和时间,jQuery在时间段内不断调整CSS直到达到我们设定的值。

1
2
3
4
5
6
var div = $('#test-animate');
div.animate({
opacity: 0.25,
width: '256px',
height: '256px'
}, 3000); // 在3秒钟内CSS过渡到设定值
动画结束回调

animate()还可以再传入一个函数,当动画结束时,该函数将被调用,实际上这个回调函数参数对于基本动画也是适用的。

1
2
3
4
5
6
7
8
9
10
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');
});

动画控制

串行动画

jQuery的动画效果还可以串行执行,通过链式调用依次执行,

1
2
3
4
$("#p1")
.css("color","red")
.slideUp(2000)
.slideDown(2000);
延迟动画

通过delay()方法还可以实现暂停,这样,我们可以实现更复杂的动画效果,而代码却相当简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var div = $('#test-animates');
// 动画效果:slideDown - 暂停 - 放大 - 暂停 - 缩小
div.slideDown(2000)
.delay(1000)
.animate({
width: '256px',
height: '256px'
}, 2000)
.delay(1000)
.animate({
width: '128px',
height: '128px'
}, 2000);
}
</script>
停止动画
  • stop()方法用于在动画或效果完成前对它们进行停止。
  • stop() 方法适用于所有 jQuery 效果函数,包括滑动、淡入淡出和自定义动画。
语法格式
1
$(selector).stop(stopAll,goToEnd);
  • 可选的 stopAll 参数规定是否应该清除动画队列。默认是 false,即仅停止活动的动画,允许任何排入队列的动画向后执行。
  • 可选的 goToEnd 参数规定是否立即完成当前动画。默认是 false。
示例
1
2
3
$("#stop").click(function(){
$("#panel").stop();
});
结束回调

应用于基本的函数和自定义动画。

语法格式
1
$(selector).hide(speed,callback)
示例
1
2
3
$("p").hide(1000,function(){
alert("The paragraph is now hidden");
});

存在问题

jQuery也没有实现对background-color的动画效果,用animate()设置background-color也没有效果。这种情况下可以使用CSS3的transition实现动画效果。

Ajax

基本用法

jQuery在全局对象jQuery(也就是$)绑定了ajax()函数,可以处理AJAX请求。

ajax(url, settings)函数需要接收一个URL和一个可选的settings对象,常用的选项如下:

1
2
3
4
5
6
- async:是否异步执行AJAX请求,默认为true,千万不要指定为false;
- method:发送的Method,缺省为'GET',可指定为'POST'、'PUT'等;
- contentType:发送POST请求的格式,默认值为'application/x-www-form-urlencoded; charset=UTF-8',也可以指定为text/plain、application/json;
- data:发送的数据,可以是字符串、数组或object。如果是GET请求,data将被转换成query附加到URL上,如果是POST请求,根据contentType把data序列化成合适的格式;
- headers:发送的额外的HTTP头,必须是一个object;
- dataType:接收的数据格式,可以指定为'html'、'xml'、'json'、'text'等,缺省情况下根据响应的Content-Type猜测。

例子:发送一个GET请求,并返回一个JSON格式的数据:

1
2
3
4
var jqxhr = $.ajax('/api/categories', {
dataType: 'json'
});
// 请求已经发送了

例子:发送一个post请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
function testMethod() {
let url = "http://localhost:8083/test-api/getBean";
let param = {
tag: 'this'
};

$.ajax(url, {
dataType: 'json',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(param)
});
}

回调处理

jQuery的ajax请求对象类似一个Promise对象,我们可以用链式写法来处理各种回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function ajaxLog(s) {
var txt = $('#test-response-text');
txt.val(txt.val() + '\n' + s);
}
$('#test-response-text').val('');
var jqxhr = $.ajax('/api/categories', {
dataType: 'json'
}).done(function (data) {
ajaxLog('成功, 收到的数据: ' + JSON.stringify(data));
}).fail(function (xhr, status) {
ajaxLog('失败: ' + xhr.status + ', 原因: ' + status);
}).always(function () {
ajaxLog('请求完成: 无论成功或失败都会调用');
});

内置请求方法

对常用的AJAX操作,jQuery提供了一些辅助方法。可以直接使用辅助方法替换ajax关键字;

get请求
1
2
3
4
var jqxhr = $.get('/path/to/resource', {
name: 'Bob Lee',
check: 1
});

第二个参数如果是object,jQuery自动把它变成query string然后加到URL后面,实际的URL是:

1
/path/to/resource?name=Bob%20Lee&check=1
post方法

post()和get()类似,但是传入的第二个参数默认被序列化为application/x-www-form-urlencoded;

1
2
3
4
5
// 实际构造的数据name=Bob%20Lee&check=1作为POST的body被发送;
var jqxhr = $.post('/path/to/resource', {
name: 'Bob Lee',
check: 1
});
getJSON

getJSON()方法来快速通过GET请求,获取一个JSON对象.

1
2
3
4
5
6
var jqxhr = $.getJSON('/path/to/resource', {
name: 'Bob Lee',
check: 1
}).done(function (data) {
// data已经被解析为JSON对象了
});

跨域

可以在ajax()中设置jsonp: ‘callback’,让jQuery实现JSONP跨域加载数据。

扩展

jquery插件

可以扩展jQuery来实现自定义方法、封装通用方法;

实现思路
1
2
3
4
5
实现思路:
给jQuery对象绑定一个新方法是通过扩展$.fn对象实现的,
新函数方法内部的this在调用时被绑定为jQuery对象,
所以函数内部代码可以正常调用所有jQuery对象的方法,
jquery支持链式调用,所以新函数方法需要返回this,以支持链式调用;
编写插件原则

编写一个jQuery插件的原则:

1
2
3
4
1. 给$.fn绑定函数,实现插件的代码逻辑;
2. 插件函数最后要return this;以支持链式调用;
3. 插件函数要有默认值,绑定在$.fn.<pluginName>.defaults上;
4. 用户在调用时可传入设定值以便覆盖默认值。
实例

【实现高亮样式】

第一版. 扩展jquery实现一个背景高亮,文字高亮的方法?

1> 新增方法封装:

1
2
3
4
5
$.fn.highlight1 = function () {
// this已绑定为当前jQuery对象:
this.css('backgroundColor', '#fffceb').css('color', '#d85030');
return this;
}

2> 调用

1
2
3
4
5
6
7
8
9
<!-- HTML结构 -->
<div id="test-highlight1">
<p>什么是<span>jQuery</span></p>
<p><span>jQuery</span>是目前最流行的<span>JavaScript</span>库。</p>
</div>

<script>
$('#test-highlight1 span').highlight1().slideDown();
</script>

第二版. 实现文字高亮, 用户可自定义颜色?

1> 封装方法:

1
2
3
4
5
6
7
8
9
$.fn.highlight2 = function (options) {
// 要考虑到各种情况:
// options为undefined
// options只有部分key
var bgcolor = options && options.backgroundColor || '#fffceb';
var color = options && options.color || '#d85030';
this.css('backgroundColor', bgcolor).css('color', color);
return this;
}

2> 调用

1
2
3
4
5
6
7
8
9
10
11
<!-- HTML结构 -->
<div id="test-highlight2">
<p>什么是<span>jQuery</span> <span>Plugin</span></p>
<p>编写<span>jQuery</span> <span>Plugin</span>可以用来扩展<span>jQuery</span>的功能。</p>
</div>
<script>
$('#test-highlight2 span').highlight2({
backgroundColor: '#00a8e6',
color: '#ffffff'
});
</script>

第三版. 实现文字高亮,设置默认缺省值,同时可接受用户定义(终极版)?

1
2
3
4
5
【缺省值实现方式】
1. 使用一个简单的&&和||短路操作符,总能得到一个有效的值。
2. 使用jQuery提供的辅助方法$.extend(target, obj1, obj2, ...),
它把多个object对象的属性合并到第一个target对象中,
遇到同名属性,总是使用靠后的对象的值,也就是越往后优先级越高;
1
2
3
4
5
// 把默认值和用户传入的options合并到对象{}中并返回:
var opts = $.extend({}, {
backgroundColor: '#00a8e6',
color: '#ffffff'
}, options);

1> 封装方法:

1
2
3
4
5
6
7
8
9
10
11
12
$.fn.highlight = function (options) {
// 合并默认值和用户设定值:
var opts = $.extend({}, $.fn.highlight.defaults, options);
this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
return this;
}

// 设定默认值:
$.fn.highlight.defaults = {
color: '#d85030',
backgroundColor: '#fff8de'
}

2> 调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 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>

<script>
$.fn.highlight.defaults.color = '#659f13';
$.fn.highlight.defaults.backgroundColor = '#f2fae3';

$('#test-highlight p:first-child span').highlight();
$('#test-highlight p:last-child span').highlight({
color: '#dd1144'
});

</script>

针对特定元素的扩展

实现思路

jQuery对象有些方法只能作用在特定DOM元素上,比如submit()方法只能针对form。如果我们编写的扩展只能针对某些类型的DOM元素,可以利用filter方法的过滤,each()内部的回调函数的this绑定为DOM本身,支持链式调用,来针对特定元素进行扩展;

实例
  1. 给所有指向外链的超链接加上跳转提示?

1> 定义扩展方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$.fn.external = function () {
// return返回的each()返回结果,支持链式调用:
return this.filter('a').each(function () {
// 注意: each()内部的回调函数的this绑定为DOM本身!
var a = $(this);
var url = a.attr('href');
if (url && (url.indexOf('http://')===0 || url.indexOf('https://')===0)) {
a.attr('href', '#0')
.removeAttr('target')
.append(' <i class="uk-icon-external-link"></i>')
.click(function () {
if(confirm('你确定要前往' + url + '?')) {
window.open(url);
}
});
}
});
}

2> 使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- HTML结构 -->
<div id="test-external">
<p>如何学习<a href="http://jquery.com">jQuery</a></p>
<p>
首先,你要学习
<a href="/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000">JavaScript</a>
并了解基本的
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML">HTML</a></p>
</div>

<script>
$('#test-external a').external();
</script>
坚持原创技术分享,您的支持将鼓励我继续创作!