循环遍历集合中的jQuery对象,而不为每次迭代初始化一个新的jQuery对象
Looping through jQuery objects in a collection without initializing a new jQuery object for each iteration
我发现自己总是这样做:
$myElements.each( function(index, currentHtmltmlElement) {
var $currentJqueryElement = $(currentHtmltmlElement);
// Working with $currentJqueryElement
});
在每次迭代中初始化一个新的jQuery对象是一个巨大的性能损失。
所以我想这样做(credit也去decx@freenode):
for (var index = 0; index < $myElements.length; index++) {
var $currentJqueryElement = $myElements.eq(i);
// Working with $currentJqueryElement
}
但是我修复了一个JSPerf测试,结果证明这个代码片段的性能与第一个代码片段的性能相同!(
都太慢了!对于非常大的集合,您甚至可以注意到页面冻结。
所以我想知道在集合中迭代jQuery对象的快速方法是什么。
该方法也应尽可能方便使用。:
$items.each$item( function( $item, index ) { /* Working with $item directly. */ });
将远远优于古代for (var i=0...
的无能。
乌利希期刊指南2014-05-27
这里有一个例子。假设你有很多jQuery UI滑块:
<div class="my-slider"></div>
<div class="my-slider"></div>
<div class="my-slider"></div>
$sliders = $('.my-slider').slider();
现在您想要记录以控制每个滑块的值。你必须这样做:
$sliders.each( function(index, htmlSlider) {
$current_slider = $(htmlSlider); // This step is a huge performance penalty
console.log(
$current_slider.slider('value')
);
});
所以任务是摆脱性能损失。
您不能简单地执行$sliders.slider('value')
,因为这将只输出集合中第一个滑块的值。
你不能在循环中恢复到普通的JS,因为你不能在没有jQuery对象的情况下访问jQuery小部件。
到目前为止,所有这些方法…
-
$sliders.each( function(index, htmlSlider) { htmlSlider });
-
$sliders.each( function() { this });
-
for (var i = 0; i < $sliders.length; i++) { $sliders.eq(i); }
-
$.each
、$.makeArray
、$.map
等
…使用$sliders
的底层HTML元素数组,并且需要一个耗时的$( )
初始化来访问jQuery特性。
Try
$.each($p, function(i, v) {
test = $(v)
})
for + eq() : 702
each() : 722
this : 718
$.each() : 757 ("fastest")
你不能直接把jQuery集合分成几个部分,你只能用单独的HTML元素创建新的集合。-洛莫斯-安德烈Mikhaylov
Try (at console
, this page)
$("div"); // jQuery `collection` ? approx. `222` members, changes
// `split` 1st `101` members of jquery `obj`, or `collection`
var split_jq_obj_1 = $("div").slice(0, 111);
// `split` 2nd `101` members of jquery `obj`, or `collection`
var split_jq_obj_2 = $("div").slice(-111);
// Note `prevObject` and `selector` properties of `jQuery` `object`
// `split_jq_obj_1` and `split_jq_obj_2`
// `prevObject: e.fn.e.init[222]` , `selector: "div.slice(0,111)"`,
// `prevObject: e.fn.e.init[222]`, `selector: "div.slice(-111)"`)
// check results
console.log($("div"), split_jq_obj_1, split_jq_obj_2);
console.log($("div").length, split_jq_obj_1.length, split_jq_obj_2.length);
其他可能的方法
// `jquery` `object`, or `objects`
var arr = $.makeArray($.map($("div"), function(value, index) {
return ( index < 111 ? [$(value)] : null )
}), $.map($("div"), function(value, index) {
return ( index >= 111 ? [$(value)] : null )
}));
console.log(arr); // `collection` of `jQuery` `objects`
// iterate `jquery` object`, or `objects`,
// find `length` of `class` `item-content`
$.each($(arr), function(index, value) {
console.log($(value).find(".item-content").length) // `29` (see `iteration` at `console`)
});
// check results
$(".item-content").length; // `29`
编辑2014-05-28 Try this (pattern)
$(function () {
var sliders = $('.sliiider').slider({
min: 0,
max: 100
});
$('html').click(function () {
$.when(sliders)
.then(function (data) {
for (var i = 0; i < data.length; i++) {
// `$()` jQuery `wrapper` _not_ utilized,
// not certain about quantifying `cost`, if any,
// of utilizing jquery's `deferred` `object`s
// test by sliding several `sliders`,
// then `click` `document`, or `html`
console.log(data.eq(i).slider("value"))
};
})
});
});
jsfiddle http://jsfiddle.net/guest271314/8gVee/
fwiw,这个模式似乎也可以工作,没有使用jquery的init
包装器$()
$(function () {
var sliders = $('.sliiider').slider({
min: 0,
max: 100
});
$('html').click(function () {
$.when(sliders)
.then(function (data) {
// Note, 2nd parameter to `.each()` not utilized, here
data.each(function (i) {
// `$()` jQuery `init` `wrapper` _not_ utilized,
// within `.each()` `loop`,
// same result as utilizing `for` loop,
// "performance", or "fastest" not tested as yet
console.log(data.eq(i).slider("value"));
})
});
});
})
jsfiddle http://jsfiddle.net/guest271314/G944X/
只使用this
关键字?似乎是最快的,更不用说(客观上)最容易理解。
$myElements.each( function() {
var $currentJqueryElement = $(this);
});
http://jsperf.com/jquery-for-eq-vs-each/3 如果性能是一个问题,为什么不跳过jQuery和使用纯JS?
更新的答案
如果您想获得滑动条值(似乎只是css style "left"
的数量),您可以这样做:
var elems = document.getElementsByClassName('my-slider');
for (var i = 0; i < elems.length; i++){
console.log(elems[i].style.left); // logs : xx.xx%
}
会更快吗?也许吧。该方法适合所有用例吗?很可能不会,但对于特定的问题,它应该有效。
如果您证明我错了,我会很高兴,但我得出的结论是, jQuery集合是一个统一的对象,不能通过进行迭代,只有它所代表的HTML元素被存储为可以枚举的单独实体。你不能直接把jQuery集合分成几个部分,你只能用单独的HTML元素创建新的集合。
因此,只要有可能,就在循环中恢复原生JS特性,以提高性能。
- 如何删除对象数组中的对象:jquery
- 为一个声音元素数组创建一个音频对象jquery,javascript
- 在原型对象 jquery 上将一个按钮与另一个按钮不同
- 编辑对象 jQuery 的属性
- ajax 正在用多个调用覆盖 XHR 对象 - jQuery
- 传递值并将其显示为对象 - jquery
- 如何将变量名转换为对象jQuery的索引字符串
- 访问多个动态对象 jQuery
- 使用OptGroup从两个分离的JSon对象JQuery填充Select
- 显示对象jquery中的数据
- 清空Javascript对象(Jquery Mobile)
- null不是对象-jQuery+传单
- 当事件是由单元格中的对象jQuery引起时,如何更改该单元格的自定义属性
- 未捕获类型错误:Property '$'对象- jQuery
- 从数组对象Jquery中移除对象
- 将属性值转换为对象(jquery或javascript)
- 不知道如何排序这个JSON对象jQuery/JavaScript
- 解析和字符串化json对象jquery
- 插入对象(jquery)延迟
- HTML ' img '标签不能在对象jquery中显示为图像