文章概述
本篇文章记录jQuery的笔记。
参考资料
API中文在线文档
jQuery
概述
- $是著名的jQuery符号;
- jQuery把所有功能全部封装在一个全局变量jQuery中,而$也是一个合法的变量名,它是变量jQuery的别名。
- jQuery(selector, context)===$;
jquery的定义相当于1
2
3
4window.jQuery; // jQuery(selector, context)
window.$; // jQuery(selector, context)
$ === jQuery; // true
typeof($); // 'function'
$函数名占用
如果$这个变量不幸地被占用了,而且还不能改,那我们就只能让jQuery把$变量交出来,然后就只能使用jQuery这个变量:
1 | $; // jQuery(selector, context) |
选择器
概述
使用格式类似:
1 | $('dom_selector') |
- 返回的对象是jQuery对象是数组[];
- jQuery的选择器不会返回undefined或者null,这样的好处是你不必在下一行判断if (div === undefined)。
基础选择器
ID
按ID查找
1 | // 查找<div id="abc">: |
tag
按tag查找
按tag查找只需要写上tag名称就可以了:
1 | var ps = $('p'); // 返回所有<p>节点 |
class
按class查找注意在class名称前加一个.:
1 | var a = $('.red'); // 所有节点包含`class="red"`都将返回 |
多class节点
1 | var a = $('.red.green'); // 注意没有空格! |
属性
按属性查找
一个DOM节点除了id和class外还可以有很多属性,很多时候按属性查找会非常方便,比如在一个表单中按属性来查找:
1 | var email = $('[name=email]'); // 找出<??? name="email"> |
前后缀查找
1 | var icons = $('[name^=icon]'); // 找出所有name属性值以icon开头的DOM |
class属性查找
1 | var icons = $('[class^="icon-"]'); // 找出所有class包含至少一个以`icon-`开头的DOM |
组合查找
概述
可以将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 | $('p,div'); // 把<p>和<div>都选出来 |
层级选择器
概述
如果DOM元素具有层级关系,就可以用$(‘ancestor descendant’)来选择,层级之间用空格隔开.
父子层级选择
1 | <!-- HTML结构 --> |
1 | $('ul.lang li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>] |
多层选择
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 | $('ul.lang li'); // 选出JavaScript、Python和Lua 3个节点 |
表单相关
针对表单元素,jQuery还有一组特殊的选择器:
1 | :input:可以选择<input>,<textarea>,<select>和<button>; |
查找和过滤
当我们拿到一个jQuery对象后,还可以以这个对象为基准,进行查找和过滤。
样本:
1 | <!-- HTML结构 --> |
查找
向下查找
jquery对象的find(selector)方法;
1 | var ul = $('ul.lang'); // 获得<ul> |
向上查找
从当前节点开始向上查找,使用parent()方法:
1 | var swf = $('#swift'); // 获得Swift |
同级查找
对于位于同一层级的节点,可以通过next()查找后一个,prev()查找前一个;
1 | var swift = $('#swift'); |
高阶过滤
和函数式编程的map、filter类似,jQuery对象也有类似的方法。
filter
- 过滤掉不符合选择器条件的节点
1 | var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell |
- 传入函数,要特别注意函数内部的this被绑定为DOM对象,不是jQuery对象:
1 | var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell |
map
- map()方法把一个jQuery对象包含的若干DOM节点进行处理:
1 | var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell |
其他
jQuery对象包含不止一个DOM节点时,first()、last()和slice()方法可以返回一个新的jQuery对象,把不需要的DOM节点去掉:
1 | var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell |
操作DOM
Dom对象相互转换
jQuery对象和DOM对象之间可以互相转化,通常情况下你不需要获取DOM对象,直接使用jQuery对象更加方便。如果你拿到了一个DOM对象,那可以简单地调用$(aDomObject)把它变成jQuery对象,这样就可以方便地使用jQuery的API了。
1 | var div = $('#abc'); // jQuery对象 |
文本
- jQuery对象的jQuery对象的text()和html()方法分别获取节点的文本和原始HTML文本;
- 无参数调用text()是获取文本,传入参数就变成设置文本,html()类似;
获取文本
1 | <!-- HTML结构 --> |
修改文本
1 | var j1 = $('#test-ul li.js'); |
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 | <!-- HTML结构 --> |
显隐DOM
- 要隐藏一个DOM,我们可以设置CSS的display属性为none,利用css()方法就可以实现。不过,要显示这个DOM就需要恢复原有的display属性,这就得先记下来原有的display属性到底是block还是inline还是别的值。
- jQuery直接提供show()和hide()方法,我们不用关心它是如何修改display属性的;
- jQuery隐藏DOM节点并未改变DOM树的结构,它只影响DOM节点的显示。这和删除DOM节点是不同的。
1 | var a = $('a[target=_blank]'); |
DOM大小
利用jQuery对象的若干方法,我们直接可以获取DOM的高宽等信息,而无需针对不同浏览器编写特定代码:
1 | // 浏览器可视窗口大小: |
DOM属性
attr和removeAttr
attr()和removeAttr()方法用于操作DOM节点的属性:
1 | // <div id="test-div" name="Test" start="1">...</div> |
prop
prop()方法和attr()类似,但是对于选择控件返回boolean的属性(selected、checked)处理有所不同;
1 | <input id="test-radio" type="radio" name="test" checked value="1"> |
is
is()判断boolean返回值(推荐);
(selected、checked)
1 | var radio = $('#test-radio'); |
操作表单
对于表单元素,jQuery对象统一提供val()方法获取和设置对应的value属性:
1 | <input id="test-input" name="email" value=""> |
修改DOM结构
要添加新的DOM节点,除了通过jQuery的html()这种暴力方法外,还可以用append()方法;
添加节点
append方法
append方法:append()把DOM添加到最后。1
2
3【注意】
如果要添加的DOM节点已经存在于HTML文档中,它会首先从文档移除,然后再添加;
也就是说,用append(),你可以移动一个DOM节点。
- 可以传入HTML片段;
- 可以传入原始的DOM对象;
- 可以传入函数,但是要求返回一个字符串、DOM对象或者jQuery对象;
1 | <div id="test-div"> |
prepend方法
prepend()则把DOM添加到最前,用法与append类似
添加到指定位置
同级节点可以用after()或者before()方法,添加节点到指定节点元素之后或之前;
1 | var js = $('#test-div>ul>li:first-child'); |
删除节点
要删除DOM节点,拿到jQuery对象后直接调用remove()方法就可以了。如果jQuery对象包含若干DOM节点,实际上可以一次删除多个DOM节点:
1 | var li = $('#test-div>ul>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 | <a id="test-link" href="#0">点我试试</a> |
如果是调用外部非匿名函数,需要写入函数名称;1
2
3
4
5
6
7
8
9
10function hello() {
alert("world")
}
$(function () {
// 获取超链接的jQuery对象:
var a = $('#test-link');
// 通过on方法
a.click(hello);
});
直接绑定
jQuery对象可以直接绑定事件;
1 | <a id="test-link" href="#0">点我试试</a> |
proxy事件函数绑定this
$.proxy 方法接受一个已有的函数,并返回一个带特定上下文的新的函数。
1 | //【语法】 |
事件分类
jQuery对象能够绑定的事件分类。
鼠标事件
- click: 鼠标单击时触发;
- dblclick:鼠标双击时触发;
- mouseenter:鼠标进入时触发;
- mouseleave:鼠标移出时触发;
- mousemove:鼠标在DOM内部移动时触发;
- hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。
键盘事件
键盘事件仅作用在当前焦点的DOM上,通常是input和textarea。
- keydown:键盘按下时触发;
- keyup:键盘松开时触发;
- keypress:按一次键后触发。
其他事件
1 | - focus:当DOM获得焦点时触发; |
ready事件
ready仅作用于document对象。由于ready事件在DOM完成初始化后触发,且只触发一次,所以非常适合用来写其他的初始化代码。
用法示例
- 简单用法;
1 | <html> |
- 简化写法;
1 | $(document).ready(function () { |
- 最简化写法(推荐);
1 | // document对象的ready事件处理函数 |
事件参数
Event对象作为参数;
有些事件,如mousemove和keypress,我们需要获取鼠标位置和按键的值,否则监听这些事件就没什么意义了。所有事件都会传入Event对象作为参数,可以从Event对象上获取到更多的信息:
1 | $(function () { |
取消绑定
off方法用于取消绑定;
- 一个已被绑定的事件可以解除绑定,通过off(‘click’, function)实现;
- 无参数调用off()一次性移除已绑定的所有类型的事件处理函数。
1 | function hello() { |
手动触发事件
1 | 一个需要注意的问题是,事件的触发总是由用户操作引发的。 |
手动触发方式
- 调用input.trigger(‘change’);
- 直接调用jquery对象的无参事件方法(相当trigger()方法的简写)即可(推荐);
浏览器安全限制
在浏览器中,有些JavaScript代码只有在用户触发下才能执行,例如,window.open()函数:
1 | // 无法打开新窗口,将被浏览器屏蔽: |
内置动画
概览
1 | animate() 对被选元素应用“自定义”的动画 |
显隐动画
左上角显隐
方法:show、hide和toggle,从左上角逐渐展开或收缩的;
- 直接以无参数形式调用show()和hide(),会显示和隐藏DOM元素。
- 调用toggle()方法则根据当前状态决定是show()还是hide()。
- 只要传递一个时间参数进去,就变成了动画.
- 时间以毫秒为单位,但也可以是’slow’,’fast’这些字符串;
1 | var div = $('#test-show-hide'); |
垂直方向显隐
slideUp()和slideDown()则是在垂直方向逐渐展开或收缩的,而slideToggle()则根据元素是否可见来决定下一步动作;
用法与show、hide类似;1
2var div = $('#test-slide');
div.slideUp(3000); // 在3秒钟内逐渐向上消失
淡入淡出
fadeIn()和fadeOut()的动画效果是淡入淡出,也就是通过不断设置DOM元素的opacity属性来实现,而fadeToggle()则根据元素是否可见来决定下一步动作,用法与show、hide类似。
1 | var div = $('#test-fade'); |
滑动
滑动方法可使元素上下滑动,用法类似show动画。
- slideDown(): 向下;
- slideUp():向上;
- slideToggle():根据当前状态向上或向下;
1 | $("#flip").click(function(){ |
自定义动画
animate(),它可以实现任意动画效果。需要传入的参数就是DOM元素最终的CSS状态和时间,jQuery在时间段内不断调整CSS直到达到我们设定的值。
1 | var div = $('#test-animate'); |
动画结束回调
animate()还可以再传入一个函数,当动画结束时,该函数将被调用,实际上这个回调函数参数对于基本动画也是适用的。
1 | var div = $('#test-animate'); |
动画控制
串行动画
jQuery的动画效果还可以串行执行,通过链式调用依次执行,
1 | $("#p1") |
延迟动画
通过delay()方法还可以实现暂停,这样,我们可以实现更复杂的动画效果,而代码却相当简单:
1 | var div = $('#test-animates'); |
停止动画
- stop()方法用于在动画或效果完成前对它们进行停止。
- stop() 方法适用于所有 jQuery 效果函数,包括滑动、淡入淡出和自定义动画。
语法格式
1 | $(selector).stop(stopAll,goToEnd); |
- 可选的 stopAll 参数规定是否应该清除动画队列。默认是 false,即仅停止活动的动画,允许任何排入队列的动画向后执行。
- 可选的 goToEnd 参数规定是否立即完成当前动画。默认是 false。
示例
1 | $("#stop").click(function(){ |
结束回调
应用于基本的函数和自定义动画。
语法格式
1 | $(selector).hide(speed,callback) |
示例
1 | $("p").hide(1000,function(){ |
存在问题
jQuery也没有实现对background-color的动画效果,用animate()设置background-color也没有效果。这种情况下可以使用CSS3的transition实现动画效果。
Ajax
基本用法
jQuery在全局对象jQuery(也就是$)绑定了ajax()函数,可以处理AJAX请求。
ajax(url, settings)函数需要接收一个URL和一个可选的settings对象,常用的选项如下:
1 | - async:是否异步执行AJAX请求,默认为true,千万不要指定为false; |
例子:发送一个GET请求,并返回一个JSON格式的数据:
1 | var jqxhr = $.ajax('/api/categories', { |
例子:发送一个post请求:
1 | function testMethod() { |
回调处理
jQuery的ajax请求对象类似一个Promise对象,我们可以用链式写法来处理各种回调。
1 | function ajaxLog(s) { |
内置请求方法
对常用的AJAX操作,jQuery提供了一些辅助方法。可以直接使用辅助方法替换ajax关键字;
get请求
1 | var jqxhr = $.get('/path/to/resource', { |
第二个参数如果是object,jQuery自动把它变成query string然后加到URL后面,实际的URL是:
1 | /path/to/resource?name=Bob%20Lee&check=1 |
post方法
post()和get()类似,但是传入的第二个参数默认被序列化为application/x-www-form-urlencoded;
1 | // 实际构造的数据name=Bob%20Lee&check=1作为POST的body被发送; |
getJSON
getJSON()方法来快速通过GET请求,获取一个JSON对象.
1 | var jqxhr = $.getJSON('/path/to/resource', { |
跨域
可以在ajax()中设置jsonp: ‘callback’,让jQuery实现JSONP跨域加载数据。
扩展
jquery插件
可以扩展jQuery来实现自定义方法、封装通用方法;
实现思路
1 | 实现思路: |
编写插件原则
编写一个jQuery插件的原则:
1 | 1. 给$.fn绑定函数,实现插件的代码逻辑; |
实例
【实现高亮样式】
第一版. 扩展jquery实现一个背景高亮,文字高亮的方法?
1> 新增方法封装:1
2
3
4
5$.fn.highlight1 = function () {
// this已绑定为当前jQuery对象:
this.css('backgroundColor', '#fffceb').css('color', '#d85030');
return this;
}
2> 调用
1 | <!-- HTML结构 --> |
第二版. 实现文字高亮, 用户可自定义颜色?
1> 封装方法:
1 | $.fn.highlight2 = function (options) { |
2> 调用
1 | <!-- HTML结构 --> |
第三版. 实现文字高亮,设置默认缺省值,同时可接受用户定义(终极版)?
1 | 【缺省值实现方式】 |
1 | // 把默认值和用户传入的options合并到对象{}中并返回: |
1> 封装方法:
1 | $.fn.highlight = function (options) { |
2> 调用
1 | <!-- HTML结构 --> |
针对特定元素的扩展
实现思路
jQuery对象有些方法只能作用在特定DOM元素上,比如submit()方法只能针对form。如果我们编写的扩展只能针对某些类型的DOM元素,可以利用filter方法的过滤,each()内部的回调函数的this绑定为DOM本身,支持链式调用,来针对特定元素进行扩展;
实例
- 给所有指向外链的超链接加上跳转提示?
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 | <!-- HTML结构 --> |