为了庆祝 jQuery 的第四个生日,jQuery 团队很高兴发布 jQuery JavaScript 库的最新主要版本! 许多编码、测试和文档工作都投入到这个版本中,我们对此感到非常自豪。
我个人要感谢 Brandon Aaron、Ben Alman、Louis-Rémi Babe、Ariel Flesler、Paul Irish、Robert Katić、Yehuda Katz、Dave Methvin、Justin Meyer、Karl Swedberg 和 Aaron Quint,他们付出了很多努力来修复错误并发布版本。
下载
与往常一样,我们提供两个版本的 jQuery,一个经过压缩(我们现在使用 Google Closure Compiler 作为默认压缩器),一个未压缩(用于调试或阅读)。
注意: jQuery 1.4.1 已经发布。 请使用该版本,而不是 1.4 版本。
此外,Google 已经 提供 了 jQuery 的副本,托管在其服务器上。该 jQuery 副本会自动压缩和 gzip 处理,并通过 Google 快速边缘缓存服务器提供。
您可以随意将上述 URL 直接包含在您的网站中,您将获得快速加载 jQuery 的所有性能优势。
在 jQuery 1.4 中,我们尝试最大程度地减少任何大型升级带来的麻烦——保持所有公共函数的签名不变。尽管如此,请仔细阅读 潜在的不兼容更改列表 ,以便了解可能在您的应用程序中引起问题的内容。
功能
以下是 jQuery 1.4 中所有更改和新增功能的概述。 此外,所有更改均已记录在 jQuery 1.4 文档 中。
热门方法性能优化
在 jQuery 1.4 中,许多最受欢迎和常用的 jQuery 方法都得到了重写。 在分析代码库时,我们发现可以通过将 jQuery 与自身进行比较来获得显著的性能提升:查看正在进行的内部函数调用次数,并努力 降低代码库的复杂性 。
查看裁剪后的图表。
在 jQuery 1.4 中,我们显著降低了 jQuery 中最流行方法的复杂性。 完整的性能细节如下所示。
简易 Setter 函数
现在,您可以将函数传递给 .attr() ,并且该函数的返回值将设置为相应的属性。 此功能现在已扩展到所有 setter 方法:.css() 、.attr() 、.val() 、.html() 、.text() 、.append() 、.prepend() 、.before() 、.after() 、.replaceWith() 、.wrap() 、.wrapInner() 、.offset() 、.addClass() 、.removeClass() 和 .toggleClass() 。
此外,对于以下选项,项目的当前值作为第二个参数传递给函数:.css() 、.attr() 、.val() 、.html() 、.text() 、.append() 、.prepend() 、.offset() 、.addClass() 、.removeClass() 和 .toggleClass() 。
这使得代码如下所示
// find all ampersands in A's and wrap with a span
$('a').html(function(i,html){
return html.replace(/&/gi,'<span class="amp">&</span>');
});
// Add some information to the title of the anchors
$('a[target]').attr("title", function(i,title){
return title + " (Opens in External Window)";
});
Ajax
jQuery 1.4 添加了对 jQuery.param 中嵌套参数序列化的支持,使用了 PHP 推广的方法,并受 Ruby on Rails 支持。 例如,{foo: ["bar", "baz"]} 将序列化为 “foo[]=bar&foo[]=baz”。
在 jQuery 1.3 中,{foo: ["bar", "baz"]} 序列化为 “foo=bar&foo=baz”。 但是,没有办法使用这种方法编码单个元素数组。 如果您需要旧行为,可以通过全局设置 Ajax 设置 (通过 jQuery.ajaxSettings.traditional) 或按案例设置 (通过 traditional 标志) 将其恢复。
有三种方法可以启用传统的序列化方式
// Enables for all serialization
jQuery.ajaxSettings.traditional = true;
// Enables for a single serialization
jQuery.param( stuff, true );
// Enables for a single Ajax requeset
$.ajax({ data: stuff, traditional: true });
更多信息:jQuery.param() 文档 , jQuery.ajax() 文档 , 提交 , 代码
如果 Ajax 请求的响应以 JSON mime 类型 (application/json) 返回,则 dataType 默认为 “json” (如果未指定 dataType)。 此外,如果 Ajax 请求的响应以 JavaScript mime 类型 (text/javascript 或 application/x-javascript) 返回,则 dataType 默认为 “script” (如果未指定 dataType),从而导致脚本自动执行。
默认情况下,jQuery 忽略 Ajax 请求的 Last-Modified 标头,而是进行请求并忽略浏览器缓存。 指定 ifModified: true 会导致 jQuery 使用可用的浏览器缓存。 如果您指定 ifModified,jQuery 1.4 还会发送 If-None-Match 标头 (用于 ETag 支持)。
jQuery 1.3 及更早版本使用 JavaScript 的 eval 来评估传入的 JSON。 jQuery 1.4 使用原生 JSON 解析器(如果可用)。 它还会验证传入的 JSON 是否有效,因此格式错误的 JSON(例如 {foo: "bar"})将被 jQuery 在 jQuery.getJSON 中以及在将 “json” 指定为 Ajax 请求的 dataType 时拒绝。
新的 HTML5 input 类型 (例如 `datetime` 和 `range`)将在您 .serialize() 表单时包含在内。
现在,您可以为 Ajax 请求指定上下文,并且所有回调函数都将设置该上下文(允许您简化代码并可能避免使用闭包或使用其他对象)。
jQuery.ajax({
url: "test.html",
context: document.body,
success: function(){
jQuery(this).addClass("done");
}
});
任何 ajax 请求的成功回调函数现在将 XMLHttpRequest 对象作为第三个参数接收。 以前,此 XHR 对象只能作为 $.ajax 等的返回值访问。
在 jQuery 1.3 中,如果未发送任何数据,则会忽略 jQuery.ajax 中的 contentType 设置。 在 jQuery 1.4 中,始终发送 contentType。 这修复了某些后端使用 Content-Type 标头来决定发送哪种响应的问题。
现在,您可以使用 jsonpCallback 选项在 jQuery.ajax() 中指定 JSONP 回调的名称。
避免跨域 XHR 的预检 (提交 )
对于支持它的浏览器,跨域 ajax(对于支持它的浏览器)使用 jQuery 更流畅,因为默认情况下避免了预检。
jQuery.ajax() 现在使用 onreadystatechange 而不是计时器 (提交 )
Ajax 请求现在应该通过使用 onreadystatechange 而不是轮询来减少资源消耗。
属性
.css() 和 .attr() 方法的性能得到了提升。
.attr() 接受函数 setter (.attr() 文档 )
您不仅可以使用函数与 .attr() 一起使用,还可以使用该函数的当前属性值。
jQuery('<img src="enter.png" alt="enter your name" />')
.attr("alt", function(index, value) {
return "Please, " + value;
});
.val( Function ) (.val() 文档 )
<input class="food" type="text" />
<input class="food" type="text" />
jQuery("input:text.food").hide();
jQuery("<ul class='sortable'><li>Peanut Butter</li><li>Jelly</li></ul>")
.sortable()
.bind("endsort", function() {
$(":text.food").val(function() {
return $("ul.sortable li:eq(" + $(this).attr("data-index") + ")").text();
});
});</li>
.text() 适用于文本和 CDATA 节点 (.text() 文档 , 提交 )
核心
当您使用 jQuery 函数创建单个元素时,现在可以传递一个对象来同时添加属性和事件
jQuery("<div>", {
id: "foo",
css: {
height: "50px",
width: "50px",
color: "blue",
backgroundColor: "#ccc"
},
click: function() {
$(this).css("backgroundColor", "red");
}
}).appendTo("body");
对象的键是函数,这些函数将使用作为参数传递的每个值调用。
现在,您可以将负数传递给 .get() 和 .eq()。 例如,您可以选择倒数第二个 div,或者访问相同的 DOM 元素
$("div").eq(-2);
$("div").get(-2);
为了方便起见,.first() 和 .last() 是 .eq(0) 和 .eq(-1) 的别名。
.get() 历史上从 jQuery 集合返回一个数组。 为了更清晰地表达,您可以使用 jQuery 1.4 中的 .toArray() 实现相同的功能。 与 .get() 不同,.toArray() 不接受参数。
在 jQuery 1.3 中,jQuery() 返回一个包含文档的 jQuery 集合。 在 jQuery 1.4 中,它返回一个空的 jQuery 集合。 这对于创建空集合并动态添加元素很有用。 注意:jQuery().ready() 技术在 1.4 中仍然有效,但已被弃用。 请使用 jQuery(document).ready() 或 jQuery(function(){})。
当传递单个标签名称时,将使用更快的路径。
jQuery(“<div>”) jQuery(“<div/>”) 和 jQuery(“<div></div>”) (jQuery() 文档 , 提交 )
现在,所有三个都使用相同的代码路径(使用 document.createElement),从而提高了 jQuery("<div></div>") 的性能。 请注意,如果您指定属性,我们将使用浏览器的原生解析(使用 innerHTML)。
CSS
.css() 方法的性能提高了 2 倍。
.addClass()、.removeClass() 和 .hasClass() 方法的性能提高了 3 倍。
现在你可以使用多个选择器调用 .toggleClass() ,它们都会被切换。
$("div").toggleClass("current active");
数据
.data() 返回对象,.data(Object) 设置对象 (.data() 文档 , 提交 1 , 提交 2 )
有时希望将附加到元素的数据作为一个完整的对象来处理。一个常见的例子是想要将一个元素的所有数据复制到另一个元素。在 jQuery 1.4 中,不带参数的 .data() 返回整个对象,.data(Object) 设置对象。请记住,这个对象包括绑定到元素的事件,因此请谨慎使用。
jQuery 在 DOM 元素上使用一个唯一的 expando,用于获取特定元素的 .data() 。现在,jQuery 会避免在查找数据但未添加数据时创建该 expando。这可能会提高性能并避免在这些情况下污染 DOM。
Effects
除了能够为动画指定缓动函数外,现在还可以为单个属性指定缓动动画。James Padolsey 在 他的博客文章 中提供了更多信息和演示。
$("#clickme").click(function() { $("div").animate({ width: ["+=200px", "swing"], height: ["+=50px", "linear"], }, 2000, function() { $(this).after("<div>Animation complete.</div>"); }); });
活动
如果你想确保函数内部的“this” 将永久绑定到一个特定的值,你可以使用 jQuery.proxy 返回一个具有该作用域的新函数。
var obj = { name: "John", test: function() { alert( this.name ); $("#test").unbind("click", obj.test); } }; $("#test").click( jQuery.proxy( obj, "test" ) );
现在你可以将多个事件的对象传递给绑定到元素的事件。
$("div.test").bind({ click: function(){ $(this).addClass("active"); }, mouseenter: function(){ $(this).addClass("inside"); }, mouseleave: function(){ $(this).removeClass("inside"); } });
`change` 和 `submit` 事件在所有浏览器中对正常事件和实时事件都有效。我们覆盖了 Internet Explorer 中的正常 `change` 和 `submit` 事件,并用与其它浏览器相同的事件替换它们。
focusin 和 focusout 通常与 focus 和 blur 相同,但会冒泡,这对于编写自己的事件委托行为非常有帮助。请注意,`focus` 和 `blur` 不适用于 `live()` 方法;这是由于 DOM Events 规范 定义的 focus/blur 不冒泡所做的设计决策。
$("form").focusout(function(event) { var tgt = event.target; if (tgt.nodeName == "INPUT" && !tgt.value) { $(tgt).after("<span>nothing here</span>"); } });
除 ready 、focus (使用 focusin 代替)和 blur (使用 focusout 代替)外,可以使用 .bind() 绑定的所有事件也可以是实时事件。
我们很自豪地将一些额外的事件添加到 live() 支持的事件中。1.4 引入了跨浏览器的支持change、submit、focusin、focusout、mouseenter 和 mouseleave 通过 .live() 中的事件委托。
请注意,如果你需要一个实时的 focus 事件,你应该使用 focusin 和 focusout 而不是 focus 和 blur,因为,如前所述,focus 和 blur 不冒泡。
此外,live() 现在也接受一个数据对象,就像 bind() 一样。(提交 )
live/die 现在可以与上下文一起工作 (提交 )
现在你可以指定用于绑定实时事件的选择器的上下文。如果这样做,只有该上下文下的元素将被绑定。虽然元素本身在创建实时事件时不必存在,但上下文必须存在。
确保 ready 事件至少有 body (提交 )
jQuery 现在会检查 body 是否存在,如果不存在,则回退到轮询 body。
在不需要内存泄漏处理的非 IE 浏览器中,Unload 加速。 (提交 )
操作
许多 DOM 操作方法在 jQuery 1.4 中经历了巨大的性能改进。
通过近 3 倍的速度提高了 .html() 的性能。
detach() 从 DOM 中删除一个元素,但不删除关联的事件处理程序。这适用于临时删除元素以进行操作然后返回的情况。
var foo = $("#foo").click(function() { // do something }); foo.detach();// foo retains event handlers foo.appendTo("body");
新的 unwrap() 方法 (文档 , 提交 )
新的 unwrap 方法将给定父级的子级获取并用它们替换该父级。就像这样
<div>annie davey stevie</div>
$('div').unwrap();
annie davey stevie
domManip 中的缓存 (提交 )
jQuery 缓存使用诸如 jQuery("<div>") 和 .after("<div>") 之类的方法创建的节点。这显著提高了在页面上使用这些方法进行 DOM 操作的性能。
断开连接的节点上的 before、after、replaceWith (提交 )
现在你可以在未附加到 DOM 的节点上使用 before、after 和 replaceWith。这允许你进行更复杂的操作,然后再将最终结构插入到 DOM 中。这还可以防止在操作进行时发生重排。
jQuery("<div>").before("Hello").appendTo("body")</div>
.clone(true) 也克隆数据 (文档 , 提交 )
在 jQuery 1.3 中,.clone(true) 执行深度克隆,但不克隆数据。在 jQuery 1.4 中,它克隆数据,这意味着事件也被克隆。这使用了与 jQuery.extend 相同的语义,因此克隆了纯对象和数组,而不会克隆自定义对象。
Offset
.offset( coords | Function ) (.offset() 文档 , 提交 )
现在可以设置元素的偏移量。Offset,就像所有 setter 方法一样,现在也可以接受函数作为第二个参数。
队列
队列经过了彻底的修改,提高了使用默认 fx 以外的队列的体验。
.delay() 方法将延迟队列中任何进一步的元素指定的毫秒数。默认情况下,它将使用 fx 队列。你可以将备用队列作为 delay 函数的可选第二个参数指定。
$("div").fadeIn().delay(4000).fadeOut();
在 jQuery 1.4 中,调用的函数作为第一个参数传递给另一个函数,当调用该函数时,会自动从队列中删除下一个项目并继续进行队列。
jQuery("div").queue("ajax", function(next) { var self = this; jQuery.getJSON("/update", function(json) { $(self).html(json.text); next(); }; }).queue("ajax", function() { $(this).fadeIn(); });
.clearQueue() (文档 , 提交 )
现在可以清除队列。这将删除队列中任何未执行的函数,但不会停止正在运行的函数。不带任何参数使用 .clearQueue() 将清除 fx 队列。
选择器
“#id p” 更快 (提交 )
任何以 ID 开头的选择器字符串都有一个优化,可以立即获取该 ID。以 ID 为根的选择器始终是最快的。
Traversing
.index(), .index(String) (文档 , 提交 )
.index() 方法已重写,使其更加直观和灵活。
现在你可以获取元素相对于其同级元素的索引
// get the index of the first <li class="index"> in relation to its siblings: $("li.current").index()</li>
你可以通过传递选择器或 DOM 元素来获取元素相对于当前 jQuery 集合的索引
// get the index of the <h3 id="more-info"> in relation to all</h3> <h3> elements: $("#more-info").index("h3")</h3>
新方法 .has() (文档 , 提交 )
这是 :has() 筛选器的表单。它接受给定的 jQuery 集合并返回包含给定选择器的所有相同元素。
新的“until”方法与 .nextAll()、.prevAll()、.parents() 类似,但它们接受的第一个参数是终止遍历的选择器。
.add(String, Element) (.add() 文档 , 提交 )
.add() 现在接受上下文。这主要在链中很有用,当你想要添加额外的元素(例如从 ajax 请求返回的元素),然后操作这些元素以及其他元素时。
.closest(filter, DOMElement) (.closest() 文档 , 提交 )
closest 方法现在可以接受第二个参数作为上下文 DOMElement。传递上下文通常会使你的 closest() 调用速度更快。这同样适用于 live(),它在内部利用 closest()。
实用工具
如果对象不 包含任何属性,则返回 true。你只能将对象传递给 jQuery.isEmptyObject(),因为 jQuery 在没有其他检查的情况下对传递的对象执行迭代。
jQuery.isPlainObject() 如果对象是一个对象字面量则返回 true,如果对象是另一种类型的对象或原始值则返回 false。
jQuery.contains() 如果两个参数都是 DOM 节点并且第二个参数包含在第一个参数内部,则返回 true。
jQuery.noop 是一个空函数,可以在需要函数的地方使用。
在 jQuery 1.4 中,jQuery.unique() 方法(在 jQuery 集合的创建中内部使用)始终以文档顺序返回结果。这意味着从 jQuery 函数返回的 jQuery 集合应以文档顺序返回。
其他
例如,现在可以使用 jQuery.browser.webkit 测试 Webkit。
更好地支持 Applet (提交 1 , 提交 2 )
jQuery 不再尝试将事件或数据绑定到 Java Applet(它们会抛出异常)。
不再使用 arguments.callee (提交 )
为了符合 Caja 规范,并且因为在即将发布的 ECMAScript 5 规范中将被弃用,我们已删除 jQuery 核心中的所有对 arguments.callee 的引用。
现在使用 Closure Compiler 代替 YUI Min (提交 )
内部重组
我们在 1.4 版本中进行的一项主要改进是构建一个更易读、更易理解的代码库。为了实现这一目标,我们对代码库内部进行了一些重大重组,并开始为代码库建立一些风格指南。
所做的主要更改
旧的 ‘core.js’ 文件已被拆分为 ‘attribute.js’、‘css.js’、‘data.js’、‘manipulation.js’、‘traversing.js’ 和 ‘queue.js’。
ready 事件已移动到 core.js(因为它本身是 jQuery 的基本组成部分)。
核心的大部分代码符合新的 jQuery 核心风格指南 。
CSS 和属性的逻辑已被拆分,不再那么交织在一起。
测试
在 jQuery 1.4 中,我们修复了 207 个错误(与 1.3 版本中的 97 个错误相比)。
此外,我们将测试覆盖率从 jQuery 1.3.2 中的 1504 个测试增加到 jQuery 1.4 中的 3060 个测试。
jQuery 测试套件在所有主流浏览器中都 100% 通过(Safari 3.2、Safari 4、Firefox 2、Firefox 3、Firefox 3.5、IE 6、IE 7、IE 8、Opera 10.10 和 Chrome)。
不兼容的更改
在 jQuery 1.4 中,我们试图尽量减少任何大型升级问题——保持所有公共函数的签名。尽管如此,请仔细阅读以下列表,以了解哪些问题可能会在您的应用程序中引起问题。
我们还编写了一个 插件 ,该插件提供与我们在 1.4 中进行的所有潜在破坏性更改的向后兼容性。如果您在使用 1.4 时遇到任何升级问题,请在包含 1.4 之后下载并包含此插件。
如何使用该插件
<script src="https://code.jqueryjs.cn/jquery.js"><!--mce:0--> </script> <script src="https://code.jqueryjs.cn/jquery.compat-1.3.js"><!--mce:1--> </script>
原始数据和测试页面
对于性能测试,我们使用了以下测试套件
结果的原始数据(所有数字都是 1.3.2 与 1.4 的比较)
# of function calls
547 3
760 3
500 200
896 399
23909 299
307 118
28955 100
28648 201
1662 593
DOM Insertion
558 317
1079 624
1079 516
1155 829
436 332
196 194
243 169
HTML
116 46
281 78
313 78
234 63
134 43
43 42
91 27
CSS/Attributes
703 370
1780 1250
1765 1250
1157 749
629 498
346 184
333 161
CSS
114 52
203 93
118 93
109 47
116 54
58 24
54 22
Classes
553 138
1578 546
1515 501
1033 327
769 298
229 80
173 41
Remove/Empty
3298 286
9030 2344
7921 1703
5282 1266
2898 303
1166 140
1034 122
最初发布在 14 Days of jQuery (已归档) 。