首页 > 代码库 > JQuery的开发与使用心得
JQuery的开发与使用心得
关于jQuery的
入门使用jQuery可以很容易或具有挑战性的,这取决于你如何使用JavaScript,HTML,CSS进行开发和编程。
要知道一件重要的事情是,jQuery是只是一个JavaScript库。jQuery的所有功能特性都是通过JavaScript访问,所以要对javascript足够的理解,并能使其构建和调试代码是必不可少。虽然使用jQuery定期工作可以随着时间的推移,提高使用JavaScript的熟练程度,可能没有JavaScript的内置结构和语法的应用知识写jQuery很难上手。因此,如果你是新来的JavaScript,我们建议您查看的JavaScript基础教程 Mozilla开发者网络(MDN)上,想了解jquery的具体javascript实现原理可去http://youmightnotneedjquery.com/
如何jQuery的工作原理
jQuery的:基础知识
这是一个基本的教程,旨在帮助您使用jQuery上手。如果你没有一个测试页面设置呢,通过创建以下的HTML页面开始:
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
|
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Demo</title> </head> <body> <a href=http://www.mamicode.com/"http://jquery.com/">jQuery</a> <script src=http://www.mamicode.com/"jquery.js"></script> <script> // Your code goes here. </script> </body> </html> |
该src
属性中的<script>
元素必须指向jQuery的副本。从下载的jQuery的副本下载jQuery的页面和存储jquery.js
文件在同一目录作为您的HTML文件。
jquery-x.y.z.js
。请确保该文件或者重命名jquery.js
或更新src
的属性<script>
相匹配的文件名元素。文档准备启动代码
为了确保他们的代码运行在浏览器完成加载该文件,许多JavaScript程序员包装自己的代码在后的onload
功能:
1
2
3
4
五
|
window.onload = function() { alert( "welcome" ); }; |
不幸的是尽快运行代码的文件已准备好进行操作,代码不运行,直到所有图像都下载完毕,包括横幅广告。jQuery ready事件:
1
2
3
4
五
|
$( document ).ready(function() { // Your code here. }); |
window
调用的对象jQuery
和$
,$
是一个简单的别名jQuery
,它的经常使用,因为它是更短,更快地写。例如,在里面ready
时,你可以添加一个单击处理程序的链接:
1
2
3
4
五
6
7
8
9
|
$( document ).ready(function() { $( "a" ).click(function( event ) { alert( "Thanks for visiting!" ); }); }); |
上面的jQuery代码复制到你的HTML文件,它说// Your code goes here
。然后,保存您的HTML文件,然后在浏览器中刷新测试页。点击链接现在应该先显示一个警告弹出,然后继续导航到的默认行为http://jquery.com。
对于click
大部分其他的事件,您可以通过调用阻止默认行为event.preventDefault()
的事件处理程序:
1
2
3
4
五
6
7
8
9
10
11
|
$( document ).ready(function() { $( "a" ).click(function( event ) { alert( "As you can see, the link no longer took you to jquery.com" ); event.preventDefault(); }); }); |
尝试更换您的jQuery代码,先前复制到您的HTML文件中第一个片段,与上面的之一。再次保存HTML文件并重新加载尝试一下。
完整的示例
下面的例子说明点击上面的处理代码的讨论,直接在HTML嵌入<body>
。注意,在实践中,它通常是最好将代码在一个单独的JS文件并加载它与在页面上<script>
的元素的src
属性。
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Demo</title> </head> <body> <a href=http://www.mamicode.com/"http://jquery.com/">jQuery</a> <script src=http://www.mamicode.com/"jquery.js"></script> <script> $( document ).ready(function() { $( "a" ).click(function( event ) { alert( "The link will no longer take you to jquery.com" ); event.preventDefault(); }); }); </script> </body> </html> |
添加和删除一个HTML类
ready
事件,这样,当文档准备工作在你的代码执行。另一种常见的任务就是添加或删除类。
首先,添加一些样式信息写入<head>
文件,像这样的:
2
3
4
五
|
<style> a.test { font-weight: bold; } </style> |
接下来,添加.addClass()调用脚本:
1
|
$( "a" ).addClass( "test" ); |
所有的<a>
元素现在字体加粗。
要删除现有类中,使用.removeClass() :
1
|
$( "a" ).removeClass( "test" ); |
特效
jQuery的也提供了一些方便的效果,以帮助您使您的网站脱颖而出。例如,如果你创建一个click处理函数:
1
2
3
4
五
6
7
|
$( "a" ).click(function( event ) { event.preventDefault(); $( this ).hide( "slow" ); }); |
然后单击时慢慢链接消失。
回调和函数
不像许多其他编程语言,JavaScript的,可以自由地绕过功能在稍后的时间执行。一个回调是作为参数传递给另一个函数传递与其父功能完成后执行的函数。回调是特殊的,因为他们耐心地等待执行,直到他们的父母完成。同时,浏览器可以执行其它功能或做其他各种的工作。
要使用回调,要知道如何将它们传递到它们的父功能是非常重要的。
回调不争论
如果回调没有参数,你可以将它传递这样的:
1
|
$.get( "myhtmlpage.html", myCallBack ); |
当$获得()完获取的页面myhtmlpage.html
,它执行myCallBack()
的功能。
- 注:这里的第二个参数是简单的函数名称(而不是作为一个字符串,而没有括号)。
回调与参数
带参数执行回调可能会非常棘手。
错误
此代码示例将无法正常工作:
1
|
$.get( "myhtmlpage.html", myCallBack( param1, param2 ) ); |
失败的原因是,代码执行myCallBack( param1, param2 )
立即,然后通过myCallBack()
的返回值作为第二个参数$.get()
。实际上,我们希望传递给函数myCallBack()
,而不是myCallBack( param1, param2 )
的返回值(这可能是也可能不是一个函数)。那么,如何传递myCallBack()
和包括它的参数?
推迟执行myCallBack()
其参数,你可以使用匿名函数作为包装。使用注意事项function() {
。匿名函数正是一件事:通话myCallBack()
,用的价值观param1
和param2
。
1
2
3
4
五
|
$.get( "myhtmlpage.html", function() { myCallBack( param1, param2 ); }); |
当$.get()
完成后获得的页面myhtmlpage.html
,它执行的匿名函数,该函数执行myCallBack( param1, param2 )
。
优化选择器
选择器的使用是对性能有很大的考验,所以在使用选择器的时候需要小心了。
jQuery的扩展
如果可能的话,应避使用jQuery的扩展选择器。这些扩展不能利用由本机提供的性能提升的querySelectorAll()
DOM方法,因此,需要使用的jQuery提供的选择器引擎。
1
2
3
4
五
|
// Slower (the zero-based :even selector is a jQuery extension) $( "#my-table tr:even" ); // Better, though not exactly equivalent $( "#my-table tr:nth-child(odd)" ); |
请记住,很多jQuery的扩展,包括:even
在上面的例子中,没有在CSS规范内。在某些情况下,这些扩展的便利性可能超过其性能成本。
避免过度特异性
1
2
3
4
|
$( ".data table.attendees td.gonzalez" ); // Better: Drop the middle if possible. $( ".data td.gonzalez" ); |
一个“简介的”DOM也有助于提高性能的选择,因为选择器引擎有更少的层寻找一个跨度的元素。
基于ID选择器
一个id选择器有一定的安全性。
1
2
3
4
五
|
// Fast: $( "#container div.robotarm" ); // Super-fast: $( "#container" ).find( "div.robotarm" ); |
与第一种方法相比,jQuery的查询使用DOM document.querySelectorAll()
。第二个例子中,jQuery使用document.getElementById()
,这是更快。
提示旧的浏览器
当旧的浏览器,如Internet Explorer 8和下方支撑,是必要的,请考虑以下建议:
特异性
选择器的左右侧
1
2
3
4
五
|
// Unoptimized: $( "div.data .gonzalez" ); // Optimized: $( ".data td.gonzalez" ); |
使用tag.class
如果可能的话放选择器的最右边,只是标签或只.class在选择器的最左边
。
避免通用选择
通配符选择虽然会减少代码做更多事情 ,但是效率很低。
1
2
3
4
五
6
|
$( ".buttons > *" ); // Extremely expensive. $( ".buttons" ).children(); // Much better. $( ":radio" ); // Implied universal selection. $( "*:radio" ); // Same thing, explicit now. $( "input:radio" ); // Much better. |
代码组织概念
当你超越添加简单的改进自己的网站使用jQuery并开始制定全面的客户端应用程序,你需要考虑如何组织你的代码。在本章中,我们将看看你可以在你的jQuery应用程序中使用的各种代码的组织模式和探索RequireJS依赖管理和构建系统。
关键概念
之前,我们跳进代码的组织模式,了解一些概念是所有好的代码的组织模式是很重要的。
- 您的代码应分为功能单位-模块,服务等,因此要避免把所有的代码在一个巨大的
$( document ).ready()
块。这个概念,松散的,被称为封装。 - 不要重复自己。找出相似的功能块之间,并使用继承技术,以避免重复的代码。
- 尽管jQuery的DOM为中心的性质,JavaScript应用程序是不是所有的DOM。请记住,不是所有的功能块需要 - 或者应该 - 有一个DOM表示。
- 功能单位应松耦合,即,功能单元应该能够在其自己的存在,和单元之间的通信应经由消息收发系统,诸如自定义事件或发布/订阅处理。功能单元之间保持直接沟通远只要有可能。
松散耦合的概念可能是特别麻烦的开发人员使他们的第一次涉足复杂的应用程序,从而为您开始留心这一点。
封装
第一步代码组织分离您的应用程序为不同的组件; 有时,甚至只是这方面的做的好才满足开发需要。
对象常量
一个对象字面也许是封装相关的代码最简单的方法。它不提供属性或方法的任何隐私的,但它是消除匿名函数从代码中,集中的配置选项,并简化重用和重构的路径非常有用。
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// An object literal var myFeature = { myProperty: "hello", myMethod: function() { console.log( myFeature.myProperty ); }, init: function( settings ) { myFeature.settings = settings; }, readSettings: function() { console.log( myFeature.settings ); } }; myFeature.myProperty === "hello"; // true myFeature.myMethod(); // "hello" myFeature.init({ foo: "bar" }); myFeature.readSettings(); // { foo: "bar" } |
对象上面的文字简直是分配给一个变量的对象。对象具有一个属性和几种方法。所有属性和方法都是公开的,因此您的应用程序的任何部分可以看到该对象的属性和调用方法。虽然有一个init方法,没有什么需要之前的对象是功能,它被调用。
我们如何应用此模式jQuery代码?比方说,我们有这个代码写在传统的jQuery风格:
1
2
3
4
五
6
7
8
9
10
11
12
|
// Clicking on a list item loads some content using the // list item‘s ID, and hides content in sibling list items $( document ).ready(function() { $( "#myFeature li" ).append( "<div>" ).click(function() { var item = $( this ); var div = item.find( "div" ); div.load( "foo.php?item=" + item.attr( "id" ), function() { div.show(); item.siblings().find( "div" ).hide(); }); }); }); |
如果这是我们的应用程序的范围,这样的应用是不好的。在另一方面,如果这是一块更大的应用程序中,我们会做的很好,保持这个功能不相关的功能分开。我们可能还需要移动URL出代码,并成为一个配置区域。最后,我们可能要提取链接地址,使其更容易为以后修改的功能块。
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
三十
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
// Using an object literal for a jQuery feature var myFeature = { init: function( settings ) { myFeature.config = { items: $( "#myFeature li" ), container: $( "<div class=‘container‘></div>" ), urlBase: "/foo.php?item=" }; // Allow overriding the default config $.extend( myFeature.config, settings ); myFeature.setup(); }, setup: function() { myFeature.config.items .each( myFeature.createContainer ) .click( myFeature.showItem ); }, createContainer: function() { var item = $( this ); var container = myFeature.config.container .clone() .appendTo( item ); item.data( "container", container ); }, buildUrl: function() { return myFeature.config.urlBase + myFeature.currentItem.attr( "id" ); }, showItem: function() { myFeature.currentItem = $( this ); myFeature.getContent( myFeature.showContent ); }, getContent: function( callback ) { var url = myFeature.buildUrl(); myFeature.currentItem.data( "container" ).load( url, callback ); }, showContent: function() { myFeature.currentItem.data( "container" ).show(); myFeature.hideContent(); }, hideContent: function() { myFeature.currentItem.siblings().each(function() { $( this ).data( "container" ).hide(); }); } }; $( document ).ready( myFeature.init ); |
你会注意到的第一件事是,这种做法显然比原来要长 - 再次,如果这是我们的应用程序的范围,使用对象文本很可能是矫枉过正。假设这不是我们的应用程序的范围,虽然,我们已经获得了几件事情:
- 我们已经打破我们的功能成微小的方法。在未来,如果我们想改变内容的显示方式,很明显的地方去改变它。在最初的代码中,这一步是更难找到。
- 我们已经消除了使用匿名函数。
- 我们已经搬出了代码的主体配置选项,并把它们在一个中央位置。
- 我们已经消除了链条的制约,使代码更易于重构,重新混音和重新排列。
对于重要的功能,对象文本一条长长的代码明显改善$( document ).ready()
块,因为他们让我们思考我们的功能块。然而,他们不是一大堆不仅仅是具有内部一堆函数声明更先进的$( document ).ready()
块。
模块模式
模块模式克服一些对象的文字的限制,提供变量和函数的隐私,同时如果需要的话曝光公共API。
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
// The module pattern var feature = (function() { // Private variables and functions var privateThing = "secret"; var publicThing = "not secret"; var changePrivateThing = function() { privateThing = "super secret"; }; var sayPrivateThing = function() { console.log( privateThing ); changePrivateThing(); }; // Public API return { publicThing: publicThing, sayPrivateThing: sayPrivateThing }; })(); feature.publicThing; // "not secret" // Logs "secret" and changes the value of privateThing feature.sayPrivateThing(); |
在上面的例子中,我们自执行返回的对象的匿名函数。里面的功能,我们定义了一些变量。因为变量的函数的内部定义,我们不具有的功能的外部访问它们,除非我们把它们返回的对象。这意味着函数以外没有代码访问该privateThing
变量或往changePrivateThing
功能。不过,sayPrivateThing
也有机会获得privateThing
和changePrivateThing
,因为两人都在同一范围定义sayPrivateThing
。
这种模式是强大的,因为你可以从变量名聚集,它可以给你私人的变量和函数同时揭露包括返回的对象的属性和方法的有限的API。
下面是前面的例子的修订版本,展示我们可以如何使用模块模式,而只有露出模块的一个公共方法创建相同的功能,showItemByIndex()
。
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
三十
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
// Using the module pattern for a jQuery feature $( document ).ready(function() { var feature = (function() { var items = $( "#myFeature li" ); var container = $( "<div class=‘container‘></div>" ); var currentItem = null; var urlBase = "/foo.php?item="; var createContainer = function() { var item = $( this ); var _container = container.clone().appendTo( item ); item.data( "container", _container ); }; var buildUrl = function() { return urlBase + currentItem.attr( "id" ); }; var showItem = function() { currentItem = $( this ); getContent( showContent ); }; var showItemByIndex = function( idx ) { $.proxy( showItem, items.get( idx ) ); }; var getContent = function( callback ) { currentItem.data( "container" ).load( buildUrl(), callback ); }; var showContent = function() { currentItem.data( "container" ).show(); hideContent(); }; var hideContent = function() { currentItem.siblings().each(function() { $( this ).data( "container" ).hide(); }); }; items.each( createContainer ).click( showItem ); return { showItemByIndex: showItemByIndex }; })(); feature.showItemByIndex( 0 ); }); |
当心匿名函数
无处不在的约束匿名函数是一种痛苦。他们是难以调试,维护,测试或重用。相反,使用对象文本来组织和命名您的处理程序和回调。
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
三十
31
32
33
34
|
// BAD $( document ).ready(function() { $( "#magic" ).click(function( event ) { $( "#yayeffects" ).slideUp(function() { // ... }); }); $( "#happiness" ).load( url + " #unicorns", function() { // ... }); }); // BETTER var PI = { onReady: function() { $( "#magic" ).click( PI.candyMtn ); $( "#happiness" ).load( PI.url + " #unicorns", PI.unicornCb ); }, candyMtn: function( event ) { $( "#yayeffects" ).slideUp( PI.slideCb ); }, slideCb: function() { ... }, unicornCb: function() { ... } }; $( document ).ready( PI.onReady ); |
使用CDN的好处
有几个原因,一个CDN可以受益您的网站和公司。
1.不同域
的浏览器限制并发连接(文件下载)到单个域的数量。大多数允许四个活动连接,因此第五下载被阻塞,直到以前的文件中的一个已经完全恢复。你经常可以看到这个限制的行动来自同一个站点下载多个大文件时。
CDN文件驻留在不同的域。实际上,单个CDN允许浏览器的同时下载一个进一步的四个文件。
2.文件可以预先缓存
jQuery是在网络上无处不在。有一个高概率有人访问您网站已经访问了使用谷歌CDN的网站。因此,该文件已经被缓存的浏览器和将无需再次下载。
3.高容量的基础设施,
你可能有很大的主机,但我敢打赌,它没有被谷歌,微软或雅虎提供的容量或可扩展性。更好的CDN提供更高的可用性,降低网络延时,降低丢包。
4.分布式数据中心,
如果你的主要的Web服务器是基于在达拉斯,从欧洲或亚洲的用户,当他们访问您的文件必须做出一些跨大陆电子跳。许多的CDN提供局部数据中心,这些中心是更接近用户,并导致更快的下载。
5.内置版本控制
,通常有可能链接到一个CSS文件或JavaScript库的具体版本。如果需要,可以经常要求“最新”版本。
6.使用分析
许多商业的CDN提供的文件使用情况的报告,因为他们一般每字节充电。这些报告可以补充自己的网站分析和在某些情况下,可以提供视频观看和下载一个更好的印象。
7.提高性能和节省资金
CDN的可分配负载,节省带宽,提高性能并降低现有的托管费用-通常是免费的。
JQuery的开发与使用心得