jquery入门介绍

你是否曾经见过像$(".cta").click(function(){})这样的JavaScrip代码?或许你还会思考下$(‘#X‘)是什么,若是看到这些你都以为摸不着头脑,那请必定要读完这篇文章。若是你以为上述的代码片断是不能正常工做的,那请先看一些jQuery的代码范例,你会发现连接中的代码都是这样的结构。html

 
这篇文章将会分析下面代码片断(动画化一个方形)中出现的一些关键知识点。你可能不会常常接触这样的代码,但了解一下这段代码的机制有助于你理解jQuery:
 
  1. $(document).ready(function(){
  2. $("button").click(function(){
  3. $("div").animate({height:"toggle"}).append("hi");
  4. });
  5. });
 
咱们将会逐字逐句地解释上述的代码,告诉你JavaScript函数、jQuery对象还有事件驱动编程的具体细节。但愿看完这篇文章之后,再遇到神秘的jQuery代码时你不会再头疼。
 
$是什么?
 
在你第一眼看到$的时候,有一种高大上的猜想在你心中盘旋:这必定是个很特别很复杂的JS方法。事实上,它很普通,也没有什么特殊的含义。$就是一个函数,是jQuery函数的另外一个名字罢了。
 
jQuery是一个比较简单的JavaScript库,它在浏览器兼容方面作得很好,并且还提供了许多颇有用的特性用来操做网页或者作些动画效果。
你能够先引入jQuery库的地址,而后就能使用jQuery函数(好比$)了:
 
  1. <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
 
或者你也能够直接在jQuery官网上下载它。
 
jQuery函数一般只须要一个参数,这个参数能够是一个选择器也能够是JS引用页面上的内容(好比document)。
 
选择器就是CSS的一个片断,写在{…}以前的内容就是选择器了。因此,$(“div”)和jQuery(“div”)是一个意思,就是简单粗暴地把页面上全部的<div>标签都选中,和在CSS中使用.div得到的是同一个结果。
  1. <style>
  2. div {…}
  3. </style>
还记得在代码的最开头有一个$(document)吗?这一步是要把JS变量document传入jQuery方法当中。document是由浏览器来定义的,能够直接使用,它指的是文档对象模型(DOM)的最顶层。DOM指的是各个浏览器是如何来解释页面的整个HTML结构。用jQuery写的程序是基于DOM的。
jQuery中的$(‘div’)和document.getElementsByTagNae(“div”)获得的结果大体上是同样的。
 
关键点
 
$只是一个方法,它是jQuery方法的简写也是它另外一个名字。
 
 
在$(document)以后的点(’.‘)预示着有许多方法能够被调用。必定要是一个JS对象才能使用这个点。说个最简单的,一个JS对象就是一堆属性的集合:
 
  1. var digger = new Object();
  2. digger.species = "gerbil";
  3. digger.name = "Digger";
  4. digger.color = "white";
上面代码中,变量digger是一个对象,咱们赋值了三个子对象给它:species,name和color。在面向对象编程中,这三个变量被称为成员变量。你可能更简洁地写成这样:
 
  1. var digger = {species:"gerbil", name:"Digger", color:"white"};
 
你也能够把方法当作属性赋值给一个变量。沙鼠(Gerbil)大部分时候都很安静,但他们偶尔也会发出高频meeping sort of noise。在JS中,能够这么来表示:
 
  1. function meepMeep(){
  2. alert("meep meep");
  3. }
在JS中,变量、方法和对象之间的界限是很模糊的,因此一个方法也能够被赋值到一个(成员)变量上:
 
  1. digger.speak = meepMeep;
如今你可一个调用这个方法来让沙鼠发出叫声来:
 
  1. digger.speak();
在面向对象语法中,digger.speak();是一个成员方法或者函数。在同一个对象中的方法能够互相引用,它们还能引用其余的成员变量。想象一下Digger学会了说英语,这得是多牛X的一件事啊:
 
  1. function myNameIs(){
  2. alert("Meep! I am a " + this.species);
  3. }
  4. //assign the function
  5. digger.sayMyName = myNameIs;
  6. //call the function
  7. digger.sayMyName();
在myNameIs函数中,this指的是包含它的对象,this.species就是digger.species,它的值就是’gerbil’。若是你想要不经过对象直接调用myNameIs(),那么this指的就是JS的window对象,this.species就是window.species,,在这里它的值是undefined。页面的弹框中的文字会变成”Meep! I am a undefined”。
 
对象也能够做为函数的返回值,我我的也推荐这么使用:
 
  1. function giveMeTheGerbil(){
  2. return digger;
  3. }
这么写的话,返回的就是(全局)变量/对象digger的引用,它和最初的digger是彻底同样的,因此操做它的时候你不须要有什么顾虑。
 
  1. var digger2 = giveMeTheGerbil();
  2. //alerts "Meep! I am a gerbil"
  3. digger2.sayMyName();
你也能够不经过digger2这个中间值,而是直接在giveMeTheGerbil的返回值上调用sayMayName:
 
  1. giveMeTheGerbil().sayMyName();
先不考虑内部代码,这种程序结构和例子里第一行代码是同样的:
 
  1. $(document).ready(…);
关键点
将对象简写:{name:”Digger”, species:”gerbil”},在方法中使用到的this是依附于一个对象(或者一个方法)的,它指向包含它的对象。
 
匿名函数
 
在JS中,建立函数的方法多种多样。只要你有一点编程经验那对下面的函数声明就不会陌生:
 
  1. function meepMeep(){
  2. alert("meep meep");
  3. }
在上文里咱们已经知道了函数是能够被赋值到变量上的。咱们建立了meepMeep函数,并将它赋值到digger.speak上。事实上,函数还能够被匿名地建立出来(咱们称呼这样的函数为:函数表达式),它们在声明时是没有任何名字的,声明后再被赋值到一个变量上:
 
  1. var meepMeep = function(){
  2. alert("meep meep");
  3. };
在JS中,函数能够被赋值到变量上,还能像变量同样处处传递。让咱们看看下面这个例子:
 
  1. function runMe(f){
  2. f();
  3. }
runMe函数有一个传入参数f,它将这个传入参数视做一个函数,还调用的这个函数。因此你能够这么使用runMe:
 
  1. runMe(function(){
  2. alert("meep meep");
  3. });
这样meepMeep函数就会被成功调用。若是在这个方法里,你连meepMeep的名字都不须要了,那事情就会更有趣些了。你能够直接建立它,当须要的时候再把它传入runMe来调用这个函数:
 
  1. meepMeep();
事实上,哪里都会出现meepMeep,等同于它的匿名函数也是这样的。这么调用:
  1. (function(){
  2. alert("meep meep");
  3. })();
不像上面那样,你能够用匿名函数替换掉meepMeep,虽然使用匿名函数的时候你须要在最外层添加一组括号:
 
 
在JS中,这种写法经常是用在制造变量做用域上。你能不能猜到下面这段代码的输出是什么呢?
 
  1. var x=3;
  2. (function(){
  3. var x=4; console.log("x is " + x);
  4. })();
  5. console.log ("x is " + x);
在匿名函数里的var是解题的关键点。经过var,咱们在函数内定义了一个局部变量x,它的值是4,而后经过console.log输出这个值。由于var这个关键词,函数内的x和函数外的值为3的x就是互相独立的。所以这段代码会将4和3前后打印出来。
 
如今咱们的沙鼠已经不会发出尖锐的声音了,因此在代码中咱们再也不使用alert改用console.log来打印它的结果。在现代浏览器中console.log*是可使用的(换言之,IE浏览器低版本中没法使用它),使用console.log就能安静地在浏览器控制台中输出信息。
 
咱们接着就要讲匿名函数了。jQuery的ready方法能够说是上文中的runMe函数的延时版。ready方法中的内容会等到DOM彻底加载完会后在运行。因此等到document加载完成了,下面的匿名函数才会运行:
 
  1. function(){
  2. $("button").click (…)
  3. }
若是须要在HTML文档加载完后再执行一些动做的话,程序员们一般会使用
 
  1. $(document).ready(…)。
关键点
 
匿名函数就是没有名字的函数,像function(){alert(1);}这样。它们能够被赋值到变量上、被传递到其余函数中也能够当即执行以建立出一个做用域来。
 
方法链
 
在更详细地分析代码以前,咱们要先介绍JS中一个常见的内容:方法链。方法链指的是在一行代码中执行多个函数。这真的只是上述giveMeTheGerbil()的一个扩展:
 
  1. giveMeTheGerbil().sayMyName();
如今让咱们要从新定义一下gerbil相关的方法来返回他们的引用。
  1. digger.speak = function(){
  2. alert("meep meep"); return this;
  3. }
  4. digger.sayMyName = function(){
  5. alert("Meep! I am a " + this.species); return this;
  6. }
 
这两个函数都是对digger作了一些处理后返回digger对象。代码没有作什么改动,可是将digger对象返回之后,就能够把函数串在一块儿使用:
 
  1. giveMeTheGerbil().speak().sayMyName().speak();
giveMeTheGerbil先运行,返回了digger对象的引用。因此上面那行代码等价于:
 
  1. digger.speak().sayMyName().speak();
下一步,digger对象的speak方法运行后弹窗出’meep meep’。这也能返回digger的引用,而后这行代码就变成:
  1. digger.sayMyName().speak();
在这以后,sayMyName运行后返回digger的引用……运行后会出现三个警告框:‘meep meep. Meep! I am a gerbil, meep meep’。这样的链式效果经常出如今JS中,你可能在字符串(string)对象中见到这个:
  1. var s = "I have a dagger.";
  2. console.log(s.substring(9, 15).replace("a", "i").toUpperCase());
上面的代码是获取字符串s中的子字符串,再将子字符串中的字母’a‘用’i‘代替,替换后的结果(也就是’digger’)被转为大写,而后返回打印到控制台上。
 
固然,jQuery中处处都是方法链,在咱们的例子中也能看到:
 
  1. $("div").animate({height:"toggle"}).append("hi");
$(“div”)将页面上全部的div元素获取到而后做为jQuery对象的一部分返回。基于jQuery对象调用animate方法,而后再在每一个jQuery对象上执行append。这样的做用链能够很长很长,下面这个是典型的长jQuery方法链:
 
 
总的来讲,使用这样的长方法链会形成debug和维护代码的困难。因此尽可能避免使用这样的长链,不过在压缩时它们仍是经常被使用。
 
关键点
 
对象(好比对象中的方法)的方法会返回对象的引用,而后就能基于引用使用方法链,而不须要在执行多个方法的时候还要储存中间值。
 
jQuery对象
 
咱们的例子里用了好几个jQuery方法:ready、click、animate和append。这些方法都是与jQuery对象结合使用的,和上文中digger对象的speak方法和myNameIs方法相似的机制,也和string对象的substr方法、replace方法和toUpperCase方法相似。
 
这些函数都是jQuery对象的方法,它们也都会返回一个jQuery对象。不过比起咱们例子里的digger对象和string对象,jQuery对象相对而言要复杂许多。就像早前提过的,JS中各个概念以前的界限其实比较模糊。你能够在使用方法链的时候把它视做一个对象,可是你也能够把它当作一个数组来对待:
 
  1. var mydivs = $("div");
  2. for (var i = 0; i < mydivs.length; i++) {console.log(mydivs[i].innerHTML);}
 
在这里例子中,$(“div”)将页面上全部的div元素都存储一个jQuery对象中,而后赋值到变量mydivs中。这个jQuery对象会被当作一个数组(实际上是一个NodeList)进入迭代。每次迭代都会对DOM中选出的节点作一些操做,这些节点在迭代里也是当作对象的,因此它们也有本身的属性,好比outerHTML和innerHTML。
 
也能够先把这些节点转成jQuery对象,也就是在取得节点后将它们用$()包起来(你能够把任何代码传入$中,都能将它们转成jQuery对象),再以后经过jQuery方法html()也能够获得相同的结果。
  1. var mydivs = $("div");
  2. for (var i = 0; i < mydivs.length; i++) {console.log($(mydivs[i]).html());}
上面两个方法均可以将页面上的div元素中的HTML内容打印到控制台中。
 
当你在运行像$(“div”).animate(…).append(…);这样的代码的时候,动画是会发生在全部的div元素上的,而后这些div元素会被做为jQuery对象的一部分传到方法链中的下一个函数中(在大部分jQuery函数中都是这么实现的,具体请看文档)。
 
关键点
 
jQuery的$函数还有像click、animate这样会返回jQuery对象的方法,它们都是对象或者数组的一部分。相似数组的这部分会包含DOM中节点的引用。
 
总的来看
 
如今咱们能够全局地来看这个例子了,$(document)返回的是页面自己的jQuery对象。将一个方法传入.ready(…)中,等到页面已经解析完了DOM也已经加载完成,ready(…)中的方法就会运行。
  1. function(){
  2. $("button").click(…);
  3. }
这个方法将页面中的button元素都获取到了,而后返回一个绑定了click方法的jQuery对象。click方法中还有一个匿名函数:
 
  1. function(){
  2. $("div").animate({height:"toggle"}).append("hi");
  3. }
上述的函数获取了全部的div元素,而后返回一个jQuery对象,在这个对象上显示调用了它的animate方法。传入jQuery的animate方法中的参数是animate的一系列属性,这些属性是对象的简写形式,{height:”toggle”}这句是告诉jQuery对页面上全部的div元素的高度都使用toggle效果:一开始div的高度会变成0,接着它们的高度又会动画地变回原来的值。
 
animate方法也会返回一个jQuery对象,执行完animate方法后执行append方法:每当button被点击了,就在每一个div元素中添加”hi”字符串。运行下面的HTML代码来看看咱们说的效果是什么样的,在线demo在此:
 
  1. <button>Click me</button>
  2. <div style="width:100px;height:100px;background:green;"></div>
  3. <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
  4. <script>
  5. $(document).ready(function(){
  6. $("button").click(function(){
  7. $("div").animate({height:"toggle"}).append("hi");
  8. });
  9. });
  10. </script>
每次button被点击了,绿色的div就会收起或者展开,而后添加一个新的“hi”到div中。
 
事件驱动形成的问题
 
下面这段代码看起来够简单的吧:
 
  1. //set h to 200
  2. var h = 200;
  3. $(document).ready(function(){
  4. $("button").click(function(){
  5. //animate up to h, 200 pixels high
  6. $("div").animate({height:h});
  7. });
  8. });
你可能只是但愿div的高度到200px,可是事实上从*h*被赋值为200到动画真正发生之间还可能发生了不少事情致使最终的结果和你所指望的不同。在一个复杂的jQuery应用中,变量*h*可能会被反复使用或者它的值被改写。你可能会发现div的高度只会达到50px而不是指望中的200px。这时候你须要去看看是否是别的代码改写了h的值,当执行*for (h=1; h<50; h++) {…}*来改变h的值时,你可能会有所发现。
 
坦白来讲,这个问题并非由jQuery或者匿名函数形成的,而是事件驱动编程自己就会遇到的问题。上述的代码的片断实际上是在不一样的时间点被执行的:  
  • 首次执行时($(document).ready(…))
  • 页面加载完成后($(“button”).click(…))
  • button被点击后($(“div”).animate(…))
服务端的代码(好比PHP的程序)运行是有按照从头至尾的顺序的, 从开始到结束,输入HTML以显示页面。JS也能够作到这一点,可是它若是和事件结合起来才能发挥最大做用,好比button点击事件。这就是事件驱动编程,可不只仅只有JS是这样的编程哦。手机应用背后的程序不少也都是事件驱动的,好比Objective-C、Java或者C++在处理用户与屏幕互动这块也是使用事件驱动编程的。
 
若是上面的代码转成Java后再Android手机中运行,那么在最里层的函数中的h的引用就会出现错误。这是由于h并无被声明为全局(或者是Java中的static)变量,因此里层的代码不知道h的值应该是什么。虽然了解这点也解决不了事件驱动形成的问题,不过至少之后你会想清楚要怎么使用变量。
 
避免上述问题的一个解决办法就是将你的变量放在适当的做用域中。在第一个匿名函数中声明var h变量来解决这个问题,这样局部变量h的优先级高于其余任何的全局变量h:
  1. $(document).ready (function(){
  2. //set h to 200
  3. var h = 200;
  4. $("button").click (function(){
  5. //animate up to h, 200 pixels high
  6. $("div").animate ({height:h});
  7. });
  8. });
若是你必定要使用全局变量,那就将这些全局变量命名、组合好,并在你的代码中加上适当的comment:
  1. //properties of the animation
  2. var animationConfig = {upToHeight:200};
  3. //when document is loaded
  4. $(document).ready(function(){
  5. //when any <button> element is clicked
  6. $("button").click(function(){
  7. //change the height of all <div>s
  8. $("div").animate({height:animationConfig.upToHeight});
  9. });
  10. });
结论
 
这篇文章是一篇针对初学者的介绍JS语法和如何使用jQuery使用的指南。jQuery只是一个JS库,它有一个很看起来很特别的函数:$,推荐在jQuery中使用对象的简写形式、匿名函数还有方法链。相似的库还有YUI(Yahoo User Interface)。
 
如今再看jQuery的代码时,你是否是不会再抱有过去的疑问和不肯定了呢?你已经知道它要作什么了。虽然因为事件驱动编程的复杂性,你可能不肯定何时使用它,可是你会知道怎么作。
相关文章
相关标签/搜索