【jQuery】 jQuery基础
jQuery
之前在JS的文章中提到过,JS虽然功能全面但是仍然比较接近底层,代码写起来很麻烦,而以jQuery为代表的JS库包装了很多功能,可以让代码更加简单。接下来就来简单地记录一下我学习和所知道的jQuery。
jQuery这东西似乎是06年还是09年后才有的东西,自其出现后,明显可以感觉到我们平时浏览的网页体验好了很多。以动态效果为首的各种JQ特性让网页逼格提高不止一点点。
■ 概述
jQuery 是一个 JavaScript 函数库。jQuery(下简称JQ) 库包含以下特性:
HTML 元素选取
HTML 元素操作
CSS 操作
HTML 事件函数
JavaScript 特效和动画
HTML DOM 遍历和修改
AJAX
Utilities
一个html文件如果要用JQ,那么就要先声明引用JQ库。一般做法是在<head>里的添加一个<script>,script属性要写type="text/javascript" src="jQuery.js的路径所在"。jQuery.js文件可以去jQuery.com下载,可以获得两个版本,一个版本的大小较小代码经过精简,另外一个大小较大,是供人们阅读源码和改造的版本。
如果不想下载jQuery.js的库文件的话,也可以在线地第三方的jQuery库,只要在src里面写上链接,自己就不用下载什么文件了。如
<head> <script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script> </head>
引用第三方 jQuery库,有一个好处:许多用户在访问其他站点时,或许已经从那个站点加载过 jQuery。所以结果是,当他们访问您的站点时,会从缓存中加载 jQuery,这样可以减少加载时间。同时,大多数 CDN 都可以确保当用户向其请求文件时,会从离用户最近的服务器上返回响应,这样也可以提高加载速度。
*微软和谷歌维护的JQ文件已经很老了,建议用官方的并且新一点的版本比如:<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
■ JQ基本语法
JQ的基本语法可以概括为$(selector).action()。
$符号是JQ的标志。
selector是选择器,用于选择或查找一个或一些特定的HTML元素。一方面JQ可以用CSS选择器,就像之前在CSS中提到过的那样,比如.class用于类选择,#id用于id选择,空格是子元素选择等等,可以去看CSS定位的那篇文章http://www.cnblogs.com/franknihao/p/6673339.html的元素选择器一节。另外需要注意的是,JQ的选择机制比CSS的选择要更加灵活一点。在某些时候(比如insertAfter等方法前面的selector)我们可以直接在selector的位置写上一些html代码,selector会默认把它当成一个新建的元素。实际上我们通过JQ来构造新元素就是这么干的:
var new_para = $("<p>some new text</p>") //或者 var new_para = $("<p></p>").text("some new text") //两者都可以代表创建了一个新<p>元素
另一方面JQ选择器还支持XPath的定位元素方法。XPath在Selenium的find_element_by_xpath中接触过一点。更多选择器信息可参考http://www.w3school.com.cn/jquery/jquery_ref_selectors.asp
执行selector之后返回一个jQuery对象,可以通过对象的下标来访问这个对象选出来的各个节点。比如$("p")[0]等。另外一些用于设置而不是获取的方法(通常这些方法没有返回值)都默认返回this即调用对象本身,所以jQuery支持链式调用。比如$("p").attrs("id","test").css({color:"red"})等。
action是该HTML元素可调用的一些方法,相比于JS中的那些方法JQ的方法更加简单易懂。一般情况下,大多数action方法都是支持对返回的数组进行一个遍历性质的执行的。也就是说,所有这些方法都是自带了个each()方法的。所以当我们在选中$("p").action()的时候,页面上所有p元素都会执行action,而不仅仅是第一个匹配的p元素。当然,一些明确指出返回第一个匹配元素的某些性质的方法除外,比如$("p").attr("id")就是返回第一个匹配到的p元素的id属性值。
另外,所有的JQ代码应该都放在$(document).ready(){}函数中。这个函数时说明了文档加载完成,把JQ代码写在这个里面就可以保证JQ代码在文档全部加载完成之后再执行。
■ JQ事件
和JS一样,JQ有许多事件可以调用。JS中,事件是作为一个html元素的属性出现的,而JQ中事件和事件处理函数绑定在一起,可以说一种事件就是一种action函数。最简单的用法就是:
<html> <head> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("button").click(function(){ $("p").hide(); }); }); </script> </head> <body> <h2>This is a heading</h2> <p>This is a paragraph.</p> <button>Click me</button> </body> </html>
可以看到,这些事件和事件处理都是写在head的script标签中而不是body中的script标签里,这么做是比较通行的做法。这段JQ代码也非常好懂,即当button元素被点击时,就让p元素隐藏(隐藏是JQ动画效果,后面会讲到)。
● 事件绑定 & 事件处理函数
JQ的事件有很多,但重要的是如何把事件和事件处理函数关联起来,下面是一些JQ中将事件发生元素,事件和事件处理函数关联起来的方法,其中几个可能会详细展开讲一下。更多方法参考 http://www.w3school.com.cn/jquery/jquery_ref_events.asp:
先想说明一点,下有很多事件名就是方法名的方法如click等,其往往可以带参数调用比如上面那个示例,带参数调用的时候它的意思是把click这个事件和特定的处理函数关联起来,如果不带参数地调用,那就是只在被选择元素上手动触发某个事件,比如$("button").click()被执行时就是手动触发button被点击的事件,即使没有人为地去点击它。
1. click(...) 单击事件
2. dbclick(...) 双击事件
3. blur(...) 元素失去焦点(与元素聚焦对立)事件,指的是光标不在textarea,input之类的输入框内出现。比如点一下输入框,这个输入框就聚焦了,再点下外面,输入框就失焦了。
4. focus(...) 元素聚焦事件
5. live(event, data, function) live比较特殊,首先它的作用是可以向某个被选择元素添加一个事件和相关事件处理函数的关联。看似很多于,因为其他方法都是把事件和事件处理函数包装在一个方法中了。但是live方法的作用对象不只是当前存在的元素,还没存在但是将来可能通过一些手段新加入进来的元素也会被live函数作用。比如:
<html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("p").live("click",function(){ $(this).slideToggle(); }); $("button").click(function(){ $("<p id="newly_added">This is a new paragraph.</p>").insertAfter("button"); }); }); </script> </head> <body> <p id="existed">点击任意 p 元素会令其消失。包括本段落。</p> <button>在本按钮后面插入新的 p 元素</button> <p><b>注释:</b>通过使用 live() 方法而不是 bind() 方法,新的 p 元素同样会在点击时消失。</p> </body> </html>
假如我们把live换成$("p").click(function(){$(this).slideToggle();})这种直接的click,亦或是bind("click",function{...})的话#existed的p元素被点击后会消失,但是单击button之后新加入进来的#newly_added不会在被点击之后有动作。但是用live方法绑定的事件和事件处理函数不一样,会作用到即使是新加入的元素上来。
其次data参数允许我们可以往function这个处理函数里传递一个参数(只能是一个,如果参数要很多那就把那些参数整合到一个对象变量中,用对象变量即可),这在某些时候还是很有用的。因为一般情况下处理函数的function是不允许传递除了事件对象以外的参数的,即使传递了也会被无视掉。
6. die(event, function) 其作用是把所有通过live而不是普通方式或bind方法绑定的指定事件和事件处理函数禁用。如果参数是空的话那么就全部事件和处理函数禁用掉。
7. error(...) 当元素没有正确地加载或者发生错误时就会触发error事件,而error就是规定了error事件发生时的事件处理函数。这个error其实就是bind("error",handler_function)的简写形式。
8. mousemove(...) 当鼠标在被选择元素中移动时触发mousemove事件,这个事件通常还可以和event.pageX以及event.pageY两个变量结合起来用。这里的event.pageX和pageY分别代表鼠标位于当前页面的横纵坐标,最大值分别是JS中讲到过的window.innerWidth和window.innerHeight,而event则是事件处理函数可以用的唯一参数,事件对象,比如:
<html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $(document).mousemove(function(e){ $("span").text(e.pageX + ", " + e.pageY); }); }); </script> </head> <body> <p>鼠标位于坐标: <span></span>.</p> </body> </html>
这个示例的功能就是实时显示当前鼠标位于页面的坐标了。
9. keydown/up/press(...) 又是两个相对的事件,常用于textarea以及input这种文本输入型的组件,keydown表示某个按键被按下的事件,keyup表示某个按键被抬起,两个一起用就可以对一次完整的按键操作做出相应了。而所谓的完整一次按键操作对应的事件就是keypress了。如果想知道具体哪个按键被按的话可以调用event.which属性来看,这个属性在下面一节“事件属性”中会详细讲到。
10. mouseenter/leave/out(...) mouseenter和mouseleave也是一对事件,表示鼠标进入被选元素和离开被选元素,至于out也是表示离开元素が,它和leave的不同点在于,鼠标离开被选元素的子元素,但依然在被选元素中,即使这样也会触发mouseout事件。
11. one(...) 以上所有方法都是绑定之后每次触发事件都生效的,而one方法绑定的事件和事件处理函数在整个文档的生命周期中只执行一次。其余的和bind都是一样的。
12. resize(...) 当被选元素大小被调整时发生的事件,通常被选元素是$(window)这种。
13. scroll(...) 可滚动元素每被滚动一个像素就被触发一次的事件,通常被选元素是$(window) $("textarea")这种滚动元素
14. select(...) 当输入框中文本等被选中时触发的事件(注意,select的事件是change,select元素和select事件没有半毛钱关系= =)
15. submit(...) 当form的submit按钮被点击时触发的事件,也就是表单被提交的事件
16. toggle(function1,function2,function3) 以上所有方法大多都只能为相关的事件配置一个事件处理函数, 但toggle方法可以给被选元素多个处理函数。不过这些处理函数指向的事件都是click,也就是说当被选元素被点击时调用第一个处理函数,再点击调用第二个,再点击第三个,再点击回到第一个以此类推。
17. trigger(event[,param1,param2...]) 这章最上面有说过,和事件名同名的那些方法,如果无参调用就是手动触发相关事件。除此之外,trigger(event)也是手动触发的一种方式,同时它还可以给事件传去一些参数(虽然我没试验出来怎么用这些个参数。。)
17.5. triggerHandler(event) 这个和trigger方法很类似。但是主要考虑这么一个区别,如果我们选定了元素,触发了一个事件,而这个事件本身被我们定义过会触发另一个事件,如果用了trigger那么这两个事件都会被触发,而triggerHandler只触发后者。另外还有诸如trigger返回的仍然是一个查询对象,但triggerHandler返回的是一个值;trigger会对所有匹配的元素进行触发而triggerHandler只触发第一个匹配到的元素等等区别
18. bind({event1:function1,event2:function2;}) 向匹配元素附加一个或更多事件处理器。以上的所有方法,都只能加一个事件和相应的处理函数给元素,但是我们可以通过bind方法来给元素绑定多个事件和相应的处理函数。需要注意的是,如果还是只想绑定一个事件和事件处理函数的话那么不需要写大括号,bind的形式就变成了bind(event ,data ,function)了,这也是以上大多数方法包装在它们里面的。
19. unbind(event, function) unbind和bind之间的关系就好比die和live之间的关系。不多说了
● 事件属性
事件对象有许多内置的属性。事件对象可以通过在事件处理函数中加上参数来调用,如function(event)。关于具体事件属性上面已经提到过几个了:
event.pageX/pageY 事件发生时,鼠标位于位置横纵坐标
event.which 事件发生时,按下的按键编号。
此外还有:
event.result 事件返回的最后一个值。事件处理函数有时候不直接作出操作而是返回一个值,那么可以在后面再加上一个同事件的事件处理函数,其中调用这个属性来利用上一个函数返回的值来进行操作。
event.type 事件类型,比如click, mouseover等等
event.target 发生事件的DOM元素
event.timeStamp 返回事件发生时的时间戳,以毫秒为单位
还有专属事件对象的一些方法:
event.preventDefault() 调用这个方法可以禁用被选元素发生相关事件时的默认行为,比如$("a").click(function(event){event.preventDefault()})会让所有超链接即使点击也失效
event.isDefaultPrevented() 方法返回指定的 event 对象上是否调用了preventDefault()方法
■ JQ动画
JQ内置了一些让元素“动起来”的方法,在我看来,一些现代互联网的页面非常高大上的原因就在于这些用户体验很好的动画。所以JQ的这些方法也是逼格满满。
JQ动画参考:http://www.w3school.com.cn/jquery/jquery_ref_effects.asp,调用动画的格式和事件类似,就是$(selector).anime(...)
● 最简单的动画(或者说效果,因为没有动画)是:
hide([speed[,callback]]) 隐藏被选元素,speed可以是一个数字,表示整个动画效果经历的毫秒数,也可以用"slow","fast"等默认的速度值。callback是一个函数,在动画效果完成后执行。下同
show([speed[,callback]]) 显示被选元素
toggle([speed[,callback]]) 切换隐藏和显示(如果隐藏着则显示,如果显示着则隐藏)
● 其他的一些内置效果:
slideDown([speed[,callback]]) 下拉显示动画
slideUp([speed[,callback]]) 上拉隐藏动画
slideToggle([speed[,callback]]) 上下拉隐藏显示切换
fadeIn([speed[,callback]]) 淡入动画
fadeOut([speed[,callback]]) 淡出动画
fadeToggle([speed[,callback]]) 淡入淡出切换
fadeTo(opacity[,speed[,callback]]) 将一个元素淡入/出至指定的透明度
● 除了内置的效果,用户还可以用animate方法来自定义动画
animate(style[, speed[, callback]]) style是一个指定的类似CSS的样式,animate方法的要义就是把被选元素的CSS属性更新或新增指定的CSS样式。为什么说style是个类似CSS的样式,这是因为style和普通CSS还有些不同:
第一,属性名称不是用“-”连接单词而是用驼峰形式写,比如padding-left应该写成paddingLeft;(如果你一定想写带-的话,那么请用引号把属性的名称引起来,这样也是可行的)
第二,属性的值一定要用引号引起来,比如padding,margin这种原先可以写10px的,但是在这一定要写'10px'。不同属性间用逗号分隔而不是分号。这主要是因为在这里的style是一个JS的object对象,像python的字典一样的格式,和CSS的格式是不同的。
第三,颜色属性在默认情况下是不支持的。如果想要animate方法支持颜色的变化需要另外下插件。
第四,属性的值支持相对值的形式,符号是+=,-=等,意思就是将属性的值在现有的基础上做出变化。
下面给出一个实例(http://www.w3school.com.cn/tiy/t.asp?f=jquery_animation1_multicss):
<!DOCTYPE html> <html> <head> <script src="/jquery/jquery-1.11.1.min.js"> </script> <script> $(document).ready(function(){ $("button").click(function(){ $("div").animate({ left:'250px', opacity:'0.5', height:'+=50px', width:'150px', padding:'15px', }); }); }); </script> </head> <body> <button>开始动画</button> <p>默认情况下,所有 HTML 元素的位置都是静态的,并且无法移动。如需对位置进行操作,记得首先把元素的 CSS position 属性设置为 relative、fixed 或 absolute。</p> <div style="background:#98bf21;height:100px;width:100px;position:absolute;"> <p>some inside text</p> </div> </body> </html>
● 动画队列
当一个元素绑定了多个动画的时候,就形成了一个动画队列,动画队列有很多相关方法。
queue() 显示被选元素的排队函数
dequeue() 运行被选元素的下一个排队函数
clearQueue() 对被选元素移除所有排队的函数(仍未运行的)
stop([stopAll[, goToEnd]]) stop方法停止动画队列,stopAll是个boolean,规定是否停止被选元素的所有加入队列的动画。gotoEnd也是boolean,控制当停止动画时是否默认将动画执行到底。
下面一个实例:
<html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#start").click(function(){ $("#box").animate({height:300},"slow"); $("#box").animate({width:300},"slow"); $("#box").animate({height:100},"slow"); $("#box").animate({width:100},"slow"); }); $("#stop").click(function(){ $("#box").stop(true,true); }); }); </script> </head> <body> <p><button id="start">Start Animation</button><button id="stop">Stop Animation</button></p> <div id="box" style="background:#98bf21;height:100px;width:100px;position:relative"> </div> </body> </html>
在这个实例中,点击start之后动画开始,点stop之后当前尺寸改变至这个节点结束,但之后尺寸的改变不会发生。
动画队列的代码形式:
上面的动画队列就是很安直に写了好几个$(selector).action()语句,但是这样的话浏览器会需要搜索好多次selector,其实就多个动画排列的动画队列而言,我们还可以这么写$(selector).anime1(...).anime2(...).anime3(...)等等。这种动画队列的书写方式叫做chaining,比如:$("#p1").css("color","red").slideUp(2000).slideDown(2000);就会让id是p1的元素先变成红色,再用2秒上拉隐藏,再2秒下拉显示。为了格式好看,也可以:
$("#p1").css("color","red") .slideUp(2000) .slideDown(2000);
因为JS是忽略空格的,允许这么写。
以上记录了一些关于jQuery的基本知识,包括基本语法,用法,事件的一些方法和动画效果的方法。下篇中继续回提及关于JQ如何和html文档互动,以及JQ如何通过一个元素来定位其他元素的遍历方法。
■ JQ中的仿类机制和插件开发
所谓JQ插件开发,其实就是给原生JQ再一些自己编辑的函数以供其他人调用。那么怎么样才能在JQ中增加一些自定义的函数呢?这里可以用到$.fn.extend()方法。这个方法的用法如下:
//$.xx和$jQuery.xx是一样的 $.fn.extend({ testFunc:function() { $(this).click(function(){ alert("Hello,World!"); }); } }) //相当于是说extend方法接受一个object作为参数,object中的key是你要拓展的函数名,而value就是函数的具体内容。在这样处理之后,我们相当于为现有的JQ体系增加了一个名为testFunc的函数,在后面的代码中我们就可以: $("selector").testFunc()
如果在这个自定义方法后面还要接上其他方法,那就不能忘了在自定义方法的最后要return $(this)之类的语句。
类似的还有$.extend方法也可以为JQ添加扩展方法,这样添加的方法有点类似于静态方法,属于jQuery这个总的父类。
那么为什么说这个是一种仿类的机制呢?其实我们添加的函数(或者说方法),都是在给JQ现有的一些类增加一些成员方法,然而在JQ中这些类对于普通使用者而言都是封闭的,我们不能直接通过继承类来扩展自己需要的内容,所以走了这么一个偏锋,而这体现了JQ的模仿类的功能。(瞎扯的\(≧▽≦)/)