窥探jQuery——面向JavaScript程序员

2016-02-19 16:42 6 1 收藏

今天给大家分享的是由图老师小编精心为您推荐的窥探jQuery——面向JavaScript程序员,喜欢的朋友可以分享一下,也算是给小编一份支持,大家都不容易啊!

【 tulaoshi.com - Web开发 】

  当 jQuery 在2006年1月现身时,给我的第一印象,是这玩意儿构造得很精明。基于CSS选择器(CSS selectors)来打点一切,其思路相当灵巧(参考getElementsBySelector)。但链盒工事(chaining stuff)看起来更像个噱头,并且整体看来,jQuery库提供的功能并不能覆盖所有基础性的东西。因此我断定,jQuery只会昙花一现。

  几个月以来,我逐渐明白自己想错了。从技术工艺上考量,jQuery十分凌厉。它用简洁的方法,把大量常用功能封装起来,并提供精巧的插入式API,来满足标准库之外的功能模块的实现。jQuery秉持的核心,乃DOM元素的集合(译注:通常是某些子集合)它把元素集合作为一个根本,给高度抽象出来了。最重要的,是这种遵循最佳实践的抽象,能让jQuery与其他JavaScript代码相处融洽。

  很多对jQuery的介绍,都是针对设计师和初级开发人员。接下来我想说明,为什么jQuery也会吸引那些富有经验的开发人员。

  名称空间(Namespacing)

  编写可重用的、优秀的JavaScript代码,其关键在于对名称空间的积极把控。JavaScript只拥有单一的、全局的名称空间(即window对象),而很多程序员(以及一些库)恣意地为之添加各种东西。要知道全局变量是魔鬼!聪明的开发人员,会使用类似组件模式的技术,来尽力减少全局对象的数量。

  jQuery仅向全局名称空间引入一个标记:jQuery函数/对象。其余的要么是jQuery的直接属性(译注:原文‘directy property’系笔误,应是‘direct property’),要么就是调用jQuery函数所返回的对象的方法。

  那语言升级(language enhancements)又是什么呢?大多数库会提供映射,过滤,剥离,往往是浏览器的JavaScript引擎所缺少的那些功能。还有一些库,直接扩展了JavaScript内置的String和Array类,但这是冒险的做法。String.prototype和Array.prototype也有各自的名称空间,在其内添加的属性一旦发生冲突,所带来的风险,不亚于在全局环境下的草率大意。

  在语言升级方面,jQuery提供了很多函数(功能),但每个函数都被赋给jQuery对象的属性:jQuery.each,jQuery.extend,jQuery.grep,jQuery.map,jQuery.merge以及jQuery.trim。如此一来,它们就不会跟其他代码产生冲突。

  声名狼藉的$函数(The infamous $ function)

  刚才我说到,jQuery是唯一被引入的全局标记,其实并不尽然:$标记作为jQuery的快捷方式,也被引入进来。庆幸的是,$的存在不会带来负面影响:如果你需要让原始的$起死回生(比如,这之前你的代码使用了Prototype),你可以调用jQuery.noConflict()来恢复它。

  如果你既想拥有$的便利,又不希望jQuery跟其他同样使用了全局$函数的代码发生冲突,可遵循jQuery文档所建议的惯用方式:

(function($) {  // 在这个函数体里,$可作为jQuery的引用  // 很方便,对吧?})(jQuery);

  把一切都附加到$标记的做法,曾让我认为jQuery华而不实。不过,从体系的角度来审视这种设计,一切又是非常明了的尽管我常喜欢在代码中定义自己的$快捷方式。

  选取元素(Selecting some elements)

  jQuery的每个操作,都以选取DOM中一个或更多的节点(nodes)作为开始。jQuery(拥有一种真正的面向特定领域)的选取语法,是十分有趣的,它结合了CSS 1,CSS 2,部分CSS 3语法,一些XPath语法,以及一些特定的扩展。在这里我不会做详细介绍,我只列出几个有用的例子:

jQuery('div.panel')选取了所有class="panel"的divjQuery('p#intro')选取了所有id="intro"的段落jQuery('div#content a:visible')选取了id="content"的div中所有可见的链接jQuery('input[@name=email]')选取了所有name="email"的输入域jQuery('table.orders tr:odd')选取了类名为orders的表中所有的奇数行jQuery('a[@href^="http://"]')选取了所有(以http://开头的)外部链接jQuery('p[a]')选取了所有包含一个或多个链接的段落

  上述例子中,:visible和:odd是jQuery实现的扩展,很具特色。而属性的选取使用@作为标记,其方式和XPath一样,要优于CSS 2。

  jQuery的这套选取语法包罗万象,有些类似正则表达式,想完全消化是需要花上一段时间的。

  把玩一下(Doing stuff with them)

  通过jQuery的选取操作,我们能得到一些很棒的素材(beast)。它们是一个集合,包含了DOM元素,并且类似数组那样,拥有length属性;通过索引可以访问集合中的元素。在Firebug console的交互模式下,集合也被显示成一个数组,这个特性非常有用。集合实际上是一个jQuery对象,这个对象被赋予了很多方法(methods),用来查询,修改,扩展集合中的元素。

  jQuery的方法(methods),本质上可分成三种:一种可以操作那些符合匹配的元素;一种可以返回第一个匹配到的对象的值;一种可以变更被选取的集合。

  我不会列出所有的方法(可参考visualjquery.com),但我用例子做一下说明。如果你的浏览器装了Firebug,你可以以交互方式运行这些示例代码:首先使用这个bookmarklet(译注[1])把jQuery库载入至浏览器的任意页面,然后把示例代码粘贴到Firebug console中。

jQuery('div#primary').width(300);把id="primary"的div的宽度设为300pxjQuery('p').css('line-height', '1.8em');把所有段落的line-height设为1.8emjQuery('li:odd').css({color: 'white', backgroundColor: 'black'});向间隔的list项添加两个CSS规则;注意css()函数可以用一个对象来代替两个字符串作为参数jQuery('a[@href^="http://"]').addClass('external').attr('target', '_blank');向所有(以http://开头的)外部链接添加external类,然后策略性地加上target="_blank"属性。这个示例用到了链盒(chaining),稍后会做介绍。jQuery('blockquote').each(function(el) { alert(jQuery(this).text()) });遍历页面上的每个blockquote,并显示出它的文字内容(包括HTML标签)jQuery('a').html('Click here!');用阴险的Click here!代替页面上所有的链接a的文字

  下面的示例展示了jQuery如何取得第一个匹配到的对象的值:

var width = jQuery('div').width();页面上第一个div的宽度var src = jQuery('img').attr('src');页面上第一张图片的src属性值var color = jQuery('h1').css('color');第一个h1的颜色样式值

  在jQuery 的方法构造中,蕴含着令人惬意的对称性:当向方法传递两个参数或一个对象时,方法可被用来执行设置操作;如果只向方法传递一个参数,则可以让它执行取值操作(译注:读者可对照上面的示例代码感受一下)。这种对称性设计贯穿了jQuery体系,使得API的文法更容易被记忆。

  本节最后的例子,展示了一些可变更被选取的元素集合的方法。这些方法大多都提高了检索DOM的简易程度:

jQuery('div').not('[@id]')返回那些没有id属性的divjQuery('h2').parent()返回那些是h2的直接父节点元素jQuery('blockquote').children()返回所有blockquote的子节点元素jQuery('p').eq(4).next()在页面上找到第五个段落(译注:因为集合的元素索引从0开始),然后根据节点的树层结构关系,找到并返回这个段落节点右侧的兄弟节点元素jQuery('input:text:first').parents('form')找到并返回页面上第一个type="text"的输入域所在的form节点元素,parents()的可选参数是另一个选择器

  链盒(Chaining)

  jQuery 开发团队经常夸耀jQuery的链盒理念(译注[2]),甚至在网站首页上宣扬jQuery将改变你编写JavaScript的方式。我个人感觉,这么做多少有点误导大众,我愿意告诉大家,你完全可以取jQuery之长,却应避免冗长的方法链盒(chains of methods)。

  也就是说,链盒有时会像变戏法一样。除了使用链盒将各种操作DOM的方法粘到一起,你也可以使用jQuery的end()方法,来实现在特定范围内推进或回溯你需要得到的元素。这个概念很难解释清楚。本质上讲,每次使用(诸如children()或filter())方法来改变元素集合时,你可以在这些方法之后使用end(),来重新定位你最初选取的元素集合。关于这点,Jesse Skinner在他的Simplify Ajax development with jQuery(译注[3])教程中给出了实例:

$('form#login')  // 第一步,隐藏表单中那些带有'optional'类的label  .find('label.optional').hide().end()  // 第二步,为表单的密码输入域渲染上红色边框  .find('input:password').css('border', '1px solid red').end()  // 第三步,为表单加上提交处理  .submit(function(){    return confirm('Are you sure you want to submit?');  });

  这个示例读起来就像句俏皮话。整个过程是,先选取一个表单,再在其中选取一些元素做修改,然后回溯到表单,为它定义一个submit()处理。

  示例很酷,但如果你不习惯,也可以不这么用。我就很乐意用自定义变量来规划代码。

  操作DOM(DOM Manipulation)

  jQuery提供了几个大规模操作DOM的卓越方法。第一种非常让人惊叹:jQuery()函数能把HTML片段插入DOM元素中(实际上,函数会留意以''打头的字符串参数):

var div = jQuery('divSome text/div');

  一旦你创建好了div,便可以继续用链盒向其添加属性:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

var div = jQuery('divSome text/div').addClass('inserted').attr('id', 'foo');

  现在把div加到body上:

div.appendTo(document.body)

  或用选择器把div加到已知元素的前面:

div.prependTo('div#primary')

  处理事件(Handling events)

  任何JavaScript库都需要事件处理能力,jQuery也不例外。类似attr()和css()的行为,各种与事件处理相关的方法也有双重用途:一种是把函数当作参数,赋给事件处理器;一种是不带参数,可以模拟事件被触发(译注:前提是事件已经定义,可参考visualjquery.com Events click()):

  jQuery('p').click(function() { jQuery(this).css('background-color', 'red'); }); 为所有段落增加点击事件,当你点击它们时,段落背景会变成红色 jQuery('p:first').click() 然后在第一个段落上模拟点击的动作,它的背景会变成红色

  类似的函数还包括mouseover,keyup等,对应着浏览器通常支持的那些动作。留意一下事件处理中的'this'关键字,它代表触发事件的元素;jQuery(this)是一种惯用语法,可以让this所代表的元素应用各种jQuery方法。

  这里有两个与事件相关的函数值得仔细说一下:

jQuery('a').hover(function() {  jQuery(this).css('background-color', 'orange');}, function() {  jQuery(this).css('background-color', 'white');});

  hover()可设定两个函数,分别对应onmouseover和onmouseout事件。

jQuery('p').one('click', function() { alert(jQuery(this).html()); });

  

  one()设定的事件在第一次被触发后便被移除。上面的示例会让所有段落在第一次被点击时显示其文字内容。

  凭借bind()和trigger()方法,jQuery也可以支持自定义事件(click()家族仅仅是便捷方法,只支持有限的事件)。自定义事件可接受参数,trigger()可接受数组作为参数,来做各种处理操作:

jQuery(document).bind('stuffHappened', function(event, msg) {  alert('stuff happened: ' + msg);});jQuery(document).trigger('stuffHappened', ['Hello!']);

  渐进式编码(Unobtrusive scripting)

  本小节的标题很令我钟意。我一直认为,最好的Web应用程序,往往是那些在脚本被禁用后仍能正常使用的程序。想建立这样的应用程序,最好的方法就是遵循渐进式编码,让普通页面完全加载后,再为页面中的元素赋以事件处理(更多信息可参考渐进式编码和Hijax)。

  jQuery对这种编码策略提供了绝好支持。首先,从整体上看,节点选取暗合jQuery以及渐进式编码的核心理念。其次,针对window.onload问题,jQuery提供了一套解决方案,这套方案借鉴了Dean Edward的成果,使得以DOM加载完毕为信号的事件能跨浏览器工作。你可以在浏览器完全加载DOM后设定并运行一个函数,如下所示:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

jQuery(document).ready(function() {  alert('The DOM is ready!');});

  你甚至可以直接传递一个函数给jQuery(),以更简洁的方式达到同样效果:

来源:http://www.tulaoshi.com/n/20160219/1612869.html

延伸阅读
程序员的技能专长怎么写?下面给大家提供的简历技巧,希望可以帮到您,祝您生活愉快,找到称心如意的工作! 一、熟练面向对象编程思想,扎实的Java基础知识,精通Jsp、Servlet、Jdbc下的编程开发。 精通Struts、Hibernate、Spring开源框架,并熟练运用MVC设计模式,并具有使用这些技术的丰富经验。 熟练使用MyEclipse、Dream...
C# 中的事件与VB中的事件作用相同。但是在C# 中,任何类都可以产生一套事件,并且任何对象都可以捆绑这些事件。C# 中的事件是以Delegates为基础的。设计事件时,通常认为Delegates要接受两个参数:第一个参数是引起事件的对象,第二个参数是以个包含事件自变量的对象。 现在我们为一个事件定义一个Delegates,当有新邮件到来时将激...
public sealed class x { } Internal 如果将Internal 修饰符放在一个类或成员上,那么这个类或成员就只能被同一个汇编中的其它类使用。这与 VB 中的 Friend 修饰符相同。 Protected Protected修饰符用于准许对从这个类中派生出来的类进行访问。 Internal Protected Internal Protected 表示允许...
虚拟函数就是指:在要确定究竟调用哪个方法(一个基本类或派生类中的一个)的地方被延迟的函数。根据类型不同,函数将延迟到运行时间。比如说,有一个类‘CivilEngineer’,它含有一个方法叫做‘Charge’。这个类是从Engineer 中派生出来的,而且Engineer也有一个方法叫做‘Charge’。这时,一个虚拟函数将允许运行时间判断对象是一个 Engineer...
“这可能是我所读过的关于C++的最好的书,我为通过这本书所学到的大量C++知识而惊异,”Synesis Software公司的开发顾问Matthew Wilson如此评价着C++ Gotchas(由Pearson的Addison-Wesley出版)。 令人兴奋的是,中国青年出版社引进了该书版权,进行了严谨的本地化工作,出版了该书的中文版《C++程序设计陷阱》,为国内众多程序...

经验教程

913

收藏

33
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部