jQuery技巧和窍门

句法

  • roosteronacid 准备事件的速记
  • 由罗他酸引起的断行和可链接性
  • 由Nathan Long 嵌套filter
  • 通过roosteronacid caching集合并在同一行执行命令
  • 包含由roosteronacid select
  • 在由roosteronacid 创build元素时定义属性
  • 像使用roosteronacid 数组一样访问jQuery函数
  • noConflict函数 – 释放 Oli 的$variables
  • 用nickf 在noConflict模式下隔离$variables
  • 由roosteronacid 没有冲突模式

数据存储

  • 数据函数 -通过TenebrousX 将数据绑定到元素
  • HTML5数据属性支持,类固醇! 由roosteronacid
  • FilipDupanović 的jQuery元数据插件

优化

  • 通过roosteronacid 优化复杂select器的性能
  • 上下文参数由lupefiasco
  • 保存并重用Nathan Long的search
  • 创buildHTML元素并保存引用,检查元素是否存在,由Andreas Grech 编写自己的select器

  • 用红色方块检查集合中元素的索引
  • TM的现场活动处理程序
  • 用 ken replace名字函数的匿名函数
  • 微软AJAX框架和 Slace的jQuery桥梁
  • 由egyamado jQuery教程
  • 从集合中删除元素并保留roosteronacid的可链接性
  • 在 Ben 的匿名函数开头声明$ this
  • FireBug lite,Hotbox插件,通过Color Blend 告诉图像何时加载和Google CDN
  • 明智地使用 harriyott 的第三方jQuery脚本
  • Jan Zich 的每个function
  • Chris S的表单扩展插件
  • 由OneNerd asynchronous每个函数
  • jQuery模板插件:使用 roosteronacid的渲染函数实现复杂的逻辑

创build一个HTML元素并保存一个引用

var newDiv = $("<div />"); newDiv.attr("id", "myNewDiv").appendTo("body"); /* Now whenever I want to append the new div I created, I can just reference it from the "newDiv" variable */ 

检查一个元素是否存在

 if ($("#someDiv").length) { // It exists... } 

编写自己的select器

 $.extend($.expr[":"], { over100pixels: function (e) { return $(e).height() > 100; } }); $(".box:over100pixels").click(function () { alert("The element you clicked is over 100 pixels height"); }); 

jQuery的data()方法是有用的,并不为人所知。 它允许你在不修改DOM的情况下将数据绑定到DOM元素。

嵌套filter

你可以嵌套filter(如这里所示的nickf )。

 .filter(":not(:has(.selected))") 

我真的不是$(document).ready(fn)快捷方式的粉丝。 当然,它减less了代码,但也削弱了代码的可读性。 当你看到$(document).ready(...) ,你知道你在看什么。 $(...)以太多其他方式用于立即有意义。

如果你有多个框架,你可以使用jQuery.noConflict(); 正如你所说,但你也可以为它分配一个不同的variables:

 var $j = jQuery.noConflict(); $j("#myDiv").hide(); 

如果你有几个框架可以被分解成$x(...)风格的调用,那么它非常有用。

Ooooh,让我们不要忘记jQuery的元数据 ! data()函数很好,但是它必须通过jQuery调用来填充。

而不是打破W3C遵守自定义元素属性,如:

 <input name="email" validation="required" validate="email" minLength="7" maxLength="30"/> 

使用元数据代替:

 <input name="email" class="validation {validate: email, minLength: 2, maxLength: 50}" /> <script> jQuery('*[class=validation]').each(function () { var metadata = $(this).metadata(); // etc. }); </script> 

生活事件处理程序

为与select器匹配的任何元素设置事件处理程序,即使在初始页面加载后将其添加到DOM:

 $('button.someClass').live('click', someFunction); 

这允许你通过ajax加载内容,或者通过javascript添加它们,并让事件处理程序自动为这些元素设置正确的值。

同样,要停止实时事件处理:

 $('button.someClass').die('click', someFunction); 

与常规事件相比,这些现场事件处理程序有一些局限性,但是对于大多数情况,这些处理程序非常有效。

欲了解更多信息,请参阅jQuery文档 。

更新: live()die()在jQuery 1.7中被弃用。 有关类似的replacefunction,请参阅http://api.jquery.com/on/和http://api.jquery.com/off/

UPDATE2: live()已经被弃用了,甚至在jQuery 1.7之前。 对于1.7之前版本的jQuery 1.4.2+,使用delegate()undelegate() 可以使用delegate()来重写live()示例( $('button.someClass').live('click', someFunction); ): $(document).delegate('button.someClass', 'click', someFunction);

用命名函数replace匿名函数。 这实际上取代了jQuery上下文,但是由于它依赖于callback函数,它在使用jQuery的时候看起来就更像了。 内联匿名函数的问题在于它们更难以debugging(更容易查看具有明显命名函数的调用堆栈,而不是6个级别的“匿名”),以及同一个匿名函数jQuery链可能变得难以阅读和/或维护。 另外,匿名函数通常不会被重用。 另一方面,声明命名函数鼓励我编写更可能被重用的代码。

插图; 代替:

 $('div').toggle( function(){ // do something }, function(){ // do something else } ); 

我更喜欢:

 function onState(){ // do something } function offState(){ // do something else } $('div').toggle( offState, onState ); 

在元素创build时定义属性

在jQuery 1.4中,当你创build一个元素时,你可以使用一个对象字面值来定义属性:

 var e = $("<a />", { href: "#", class: "a-class another-class", title: "..." }); 

…你甚至可以添加样式:

 $("<a />", { ... css: { color: "#FF0000", display: "block" } }); 

这是一个链接到文档 。

而不是使用不同的别名为jQuery对象(当使用noConflict)时,我总是写我的jQuery代码通过封闭所有closures。 这可以在document.ready函数中完成:

 var $ = someOtherFunction(); // from a different library jQuery(function($) { if ($ instanceOf jQuery) { alert("$ is the jQuery object!"); } }); 

或者你可以这样做:

 (function($) { $('...').etc() // whatever jQuery code you want })(jQuery); 

我觉得这是最便携的。 我一直在同时使用Prototype和jQuery的网站上工作,这些技术避免了所有的冲突。

检查索引

jQuery的.index,但它是一个痛苦的使用,因为你需要的元素列表,并传入你想要的索引元素:

 var index = eg $('#ul>li').index( liDomObject ); 

以下更容易:

如果你想知道一个无序列表中的一个元素(例如列表项)的索引:

 $("ul > li").click(function () { var index = $(this).prevAll().length; }); 

准备事件的速记

显而易见的方式:

 $(document).ready(function () { // ... }); 

简写:

 $(function () { // ... }); 

在核心jQuery函数上,除了selector参数之外,还指定了上下文参数。 指定上下文参数允许jQuery从DOM中更深的分支开始,而不是从DOM根开始。 给定一个足够大的DOM,指定上下文参数应该转化为性能增益。

示例:在文档的第一个表格中查找所有types无线电的input。

 $("input:radio", document.forms[0]); 

参考: http : //docs.jquery.com/Core/jQuery#expressioncontext

不是真的只有jQuery,但我为jQuery和MS AJAX做了一个很好的桥梁:

 Sys.UI.Control.prototype.j = function Sys$UI$Control$j(){ return $('#' + this.get_id()); } 

如果你正在做大量的ASP.NET AJAX,真的很不错,因为现在MS支持jQuery,所以jQuery操作确实很简单:

 $get('#myControl').j().hide(); 

所以上面的例子不是很好,但是如果你正在编写ASP.NET AJAX服务器控件,可以很容易地在你的客户端控件实现中使用jQuery。

优化复杂select器的性能

在使用复杂select器时查询DOM的子集显着提高了性能:

 var subset = $(""); $("input[value^='']", subset); 

说到技巧和窍门,以及一些教程。 我发现Jeffery Way的这些系列教程( “jQuery for Absolute Beginners”video系列)非常有帮助。

它针对那些刚接触jQuery的开发人员。 他演示了如何用jQuery创build许多很酷的东西,比如animation,创build和删除元素等等…

我从中学到了很多东西。 他展示了如何使用jQuery。 现在我喜欢它,即使它很复杂,我也可以阅读和理解任何jQuery脚本。

这里有一个例子,我喜欢“ 调整文本大小

1- jQuery …

 <script language="javascript" type="text/javascript"> $(function() { $('a').click(function() { var originalSize = $('p').css('font-size'); // get the font size var number = parseFloat(originalSize, 10); // that method will chop off any integer from the specified variable "originalSize" var unitOfMeasure = originalSize.slice(-2);// store the unit of measure, Pixle or Inch $('p').css('font-size', number / 1.2 + unitOfMeasure); if(this.id == 'larger'){$('p').css('font-size', number * 1.2 + unitOfMeasure);}// figure out which element is triggered }); }); </script> 

2- CSS样式…

 <style type="text/css" > body{ margin-left:300px;text-align:center; width:700px; background-color:#666666;} .box {width:500px; text-align:justify; padding:5px; font-family:verdana; font-size:11px; color:#0033FF; background-color:#FFFFCC;} </style> 

2- HTML …

 <div class="box"> <a href="#" id="larger">Larger</a> | <a href="#" id="Smaller">Smaller</a> <p> In today's video tutorial, I'll show you how to resize text every time an associated anchor tag is clicked. We'll be examining the “slice”, “parseFloat”, and “CSS” Javascript/jQuery methods. </p> </div> 

强烈推荐这些教程…

http://blog.themeforest.net/screencasts/jquery-for-absolute-beginners-video-series/

asynchronouseach()函数

如果运行jquery的文档非常复杂 each()函数在迭代期间locking浏览器,并且/或者Internet Explorerpopup“ 是否要继续运行此脚本 ”消息,则此解决scheme将节省一天的时间。

 jQuery.forEach = function (in_array, in_pause_ms, in_callback) { if (!in_array.length) return; // make sure array was sent var i = 0; // starting index bgEach(); // call the function function bgEach() { if (in_callback.call(in_array[i], i, in_array[i]) !== false) { i++; // move to next item if (i < in_array.length) setTimeout(bgEach, in_pause_ms); } } return in_array; // returns array }; jQuery.fn.forEach = function (in_callback, in_optional_pause_ms) { if (!in_optional_pause_ms) in_optional_pause_ms = 10; // default return jQuery.forEach(this, in_optional_pause_ms, in_callback); // run it }; 

你可以使用它的第一种方法就像each():

 $('your_selector').forEach( function() {} ); 

可选的第二个参数可以指定迭代之间的速度/延迟,这对于animation可能有用( 下面的示例将在迭代之间等待1秒 ):

 $('your_selector').forEach( function() {}, 1000 ); 

请记住,因为这是asynchronous工作的,所以在下一行代码之前不能依赖迭代完成,例如:

 $('your_selector').forEach( function() {}, 500 ); // next lines of code will run before above code is complete 

我写了这个内部项目,虽然我相信它可以改进,但它为我们所需要的,所以希望你们有些人觉得它有用。 谢谢 –

语法简写-sug-thing – 在一行上caching对象集合并执行命令:

代替:

 var jQueryCollection = $(""); jQueryCollection.command().command(); 

我做:

 var jQueryCollection = $("").command().command(); 

一个有点“真实”的用例可能是这样的:

 var cache = $("#container div.usehovereffect").mouseover(function () { cache.removeClass("hover").filter(this).addClass("hover"); }); 

我喜欢在匿名函数的开头声明一个$thisvariables,所以我知道我可以引用jQueried这个。

像这样:

 $('a').each(function() { var $this = $(this); // Other code }); 

将jQuery对象保存在variables中用于重用

将一个jQuery对象保存到一个variables中,可以重复使用它,而无需通过DOM进行search以find它。

(正如@Louis所build议的,我现在用$来表示一个variables包含一个jQuery对象。)

 // Bad: searching the DOM multiple times for the same elements $('div.foo').each... $('div.foo').each... // Better: saving that search for re-use var $foos = $('div.foo'); $foos.each... $foos.each... 

作为一个更复杂的例子,假设你有一个商店的食物列表,而你只想显示符合用户标准的食物。 你有一个带checkbox的表单,每个表单都包含一个标准。 checkbox有名字organiclowfat ,并且产品有相应的类 – .organic等。

 var $allFoods, $matchingFoods; $allFoods = $('div.food'); 

现在你可以继续使用该jQuery对象。 每次单击一个checkbox(选中或取消选中),从食物主列表开始,并根据选中的框进行过滤:

 // Whenever a checkbox in the form is clicked (to check or uncheck)... $someForm.find('input:checkbox').click(function(){ // Start out assuming all foods should be showing // (in case a checkbox was just unchecked) var $matchingFoods = $allFoods; // Go through all the checked boxes and keep only the foods with // a matching class this.closest('form').find("input:checked").each(function() { $matchingFoods = $matchingFoods.filter("." + $(this).attr("name")); }); // Hide any foods that don't match the criteria $allFoods.not($matchingFoods).hide(); }); 

看来大部分有趣的和重要的技巧已经被提及,所以这个只是一个小补充。

小技巧是jQuery.each(对象,callback)函数。 每个人都可能使用jQuery.each(callback)函数遍历jQuery对象本身,因为这很自然。 jQuery.each(对象,callback)实用程序函数迭代对象和数组。 很长一段时间,我不知道除了不同的语法(我不介意写所有forms的循环),它可能是什么,我有点惭愧,直到最近才意识到它的主要优点。

问题是,因为jQuery.each(object,callback)中的循环体是一个函数 ,所以每次在循环中都会得到一个新的作用域 ,在循环中创build闭包时特别方便。

换句话说,一个典型的常见错误是做类似的事情:

 var functions = []; var someArray = [1, 2, 3]; for (var i = 0; i < someArray.length; i++) { functions.push(function() { alert(someArray[i]) }); } 

现在,当您调用functions数组中的functions ,您将得到三次警报,其中undefined的内容很可能不是您想要的。 问题是i只有一个variables,所有三个闭包都是指它。 当循环结束时, i的最终值是3,而someArrary[3]undefined 。 你可以通过调用另一个函数来解决这个问题,它会为你创build闭包。 或者你使用jQuery实用工具,它将基本上为你做:

 var functions = []; var someArray = [1, 2, 3]; $.each(someArray, function(item) { functions.push(function() { alert(item) }); }); 

现在,当你调用函数时,你会得到三个预期的内容1,2和3的警报。

一般来说,这是你自己做不了的事情,但很高兴有。

像访问数组一样访问jQuery函数

添加/删除基于布尔类的类

 function changeState(b) { $("selector")[b ? "addClass" : "removeClass"]("name of the class"); } 

是更短的版本…

 function changeState(b) { if (b) { $("selector").addClass("name of the class"); } else { $("selector").removeClass("name of the class"); } } 

没有这么多的用例。 永远不要less; 我认为这是整洁:)

更新

以防万一你不是评论阅读types,ThiefMaster指出toggleClass接受一个布尔值 ,它决定了是否应该添加或删除一个类。 所以就我上面的示例代码而言,这将是最好的方法…

 $('selector').toggleClass('name_of_the_class', true/false); 

更新:

只要在网站上包含这个脚本,你就会得到一个Firebug控制台,popup在任何浏览器中进行debugging。 不完全特色,但它仍然非常有帮助! 请记住在完成后将其删除。

 <script type='text/javascript' src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script> 

看看这个链接:

从CSS技巧

更新:我发现了一些新的东西。 它的JQuery Hotbox。

JQuery Hotbox

Google在Google代码上托pipe了几个JavaScript库。 从那里加载它可以节省带宽,并加载已经被caching的快速COS。

 <script src="http://www.google.com/jsapi"></script> <script type="text/javascript"> // Load jQuery google.load("jquery", "1.2.6"); google.setOnLoadCallback(function() { // Your code goes here. }); </script> 

要么

 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script> 

您也可以使用它来告诉图像何时完全加载。

 $('#myImage').attr('src', 'image.jpg').load(function() { alert('Image Loaded'); }); 

Firebug的“console.info”,您可以使用它来将消息和variables转储到屏幕而不必使用警报框。 “console.time”允许你轻松地设置一个计时器来包装一堆代码,看看需要多长时间。

 console.time('create list'); for (i = 0; i < 1000; i++) { var myList = $('.myList'); myList.append('This is list item ' + i); } console.timeEnd('create list'); 

在可能的情况下,使用伪select器过滤方法,以便jQuery可以使用querySelectorAll(这比嘶嘶声快得多)。 考虑这个select器:

 $('.class:first') 

同样的select可以使用:

 $('.class').eq(0) 

哪一个必须更快,因为“.class”的初始select是QSA兼容的

删除集合中的元素并保留可链接性

考虑以下几点:

 <ul> <li>One</li> <li>Two</li> <li>Three</li> <li>Four</li> <li>Five</li> </ul> 

 $("li").filter(function() { var text = $(this).text(); // return true: keep current element in the collection if (text === "One" || text === "Two") return true; // return false: remove current element from the collection return false; }).each(function () { // this will alert: "One" and "Two" alert($(this).text()); }); 

filter()函数从jQuery对象中删除元素。 在这种情况下:所有不包含文本“One”或“Two”的li元素将被删除。

更改input元素的types

当我尝试更改已经附加到DOM的input元素的types时遇到了这个问题。 您必须克隆现有元素,将其插入旧元素之前,然后删除旧元素。 否则它不起作用:

 var oldButton = jQuery("#Submit"); var newButton = oldButton.clone(); newButton.attr("type", "button"); newButton.attr("id", "newSubmit"); newButton.insertBefore(oldButton); oldButton.remove(); newButton.attr("id", "Submit"); 

明智地使用第三方jQuery脚本,比如表单字段validation或urlparsing。 这是值得一看的,所以你会知道当你下一次遇到JavaScript的要求。

换行和链接性

链接集合上的多个调用时…

 $("a").hide().addClass().fadeIn().hide(); 

您可以使用换行符来提高可读性。 喜欢这个:

 $("a") .hide() .addClass() .fadeIn() .hide(); 

触发animation时使用.stop(true,true)可以防止重复animation。 这对于翻转animation特别有用。

 $("#someElement").hover(function(){ $("div.desc", this).stop(true,true).fadeIn(); },function(){ $("div.desc", this).fadeOut(); }); 

Using self-executing anonymous functions in a method call such as .append() to iterate through something. IE:

 $("<ul>").append((function () { var data = ["0", "1", "2", "3", "4", "5", "6"], output = $("<div>"), x = -1, y = data.length; while (++x < y) output.append("<li>" + info[x] + "</li>"); return output.children(); }())); 

I use this to iterate through things that would be large and uncomfortable to break out of my chaining to build.

HTML5 data attributes support, on steroids!

The data function has been mentioned before. With it, you are able to associate data with DOM elements.

Recently the jQuery team has added support for HTML5 custom data-* attributes . And as if that wasn't enough; they've force-fed the data function with steroids, which means that you are able to store complex objects in the form of JSON, directly in your markup.

HTML:

 <p data-xyz = '{"str": "hi there", "int": 2, "obj": { "arr": [1, 2, 3] } }' /> 

JavaScript:

 var data = $("p").data("xyz"); data.str // "hi there" typeof data.str // "string" data.int + 2 // 4 typeof data.int // "number" data.obj.arr.join(" + ") + " = 6" // "1 + 2 + 3 = 6" typeof data.obj.arr // "object" ... Gobbles! Errrghh!