有什么优雅的方法把[$(div), $(span), $(li)]
变成$(div, span, li)
吗?
我需要的是一个jQuery包装的元素集,而不是一个jQuery元素数组。我希望在尽可能少的代码行中做到这一点,并且使用最少的(如果有的话)循环。
Edit:对于那些对这个问题感到困惑的人来说,这段代码是使用console.log从firebug复制并粘贴到已经被选中的元素数组上的
jQuery的map()
函数是重塑数组和/或jQuery集合的完美工具。
给定一个数组,如下所示:
var arrayOfJQ_Objects = [$("div"), $("span"), $("li")];
这一行代码就是您所需要的(在jsFiddle中查看它的实际操作):
$(arrayOfJQ_Objects).map (function () {return this.toArray(); } );
导致Firebug中的控制台显示:
jQuery(div, span, li)
参考,同时,jQuery的.toArray()
函数
如果你真正的意思是如何转换:
[$(a), $(b), $(c)]
变成:
的结果$(a, b, c)
则可以使用add函数将每个jQuery对象添加到另一个jQuery对象:
var x = $(); // empty jQuery object
$.each([$(a), $(b), $(c)], function(i, o) {x = x.add(o)});
此时,x将包含一个组合的jQuery对象,它是数组中前面的a, b和c的jQuery对象的组合。
如果没有each()
循环,我找不到任何方法。add()
函数接受一个DOM元素数组作为参数,但(至少根据文档)不是一个jQuery对象数组。
或者,您可以将每个jQuery对象转换为一个DOM元素,这可能会更有效一些,因为它只在最后生成一个新的jQuery对象:
$([$(".a"), $(".b"), $(".c")].map(function(o) { return o.get() }));
比公认的答案更简洁一点,可以使用$.fn.toArray
作为传递给$.fn.map
的参数:
var list = [$('<a>'), $('<b>'), $('<i>')];
$(list).map($.fn.toArray);
或者(这确实比较低级,但在代码中只有一个函数调用):
$.fn.map.call(list, $.fn.toArray);
可以使用add
方法将jQuery对象中的元素复制到另一个对象中。这将复制数组source
中每个jQuery对象中的所有元素到jQuery对象items
:
// Create an empty jQuery object
var items = $([]);
// Add the elements from each jQuery object to it
$.each(source, function(){ items = items.add(this); });
(在1.3.2版本之前,add
方法不支持添加jQuery对象,所以你需要使用items.add(this.get());
来代替)
假设你有一个jQuery元素数组:
let elementList = [$("selector1"), $("selector2"), $("selector3"), ...];
你可以直接在数组上使用jQuery函数($()
),它将返回一个jQuery集合:
let jQuerySetOfElements = $(elementList);
添加单个元素:
var $previousElements = $();
$previousElements.add($element);
将数组转换为jQuery的元素集:
var myjQueryElementArray = [$element1, $element2, $elementN];
$(myjQueryElementArray ).map (function () {return this.toArray(); } );
var $previousElements = $(),
myjQueryElementArray = [$element1, $element2, $elementN];
$previousElements.add($(myjQueryElementArray).map (function () {return this.toArray(); } ));
编辑:我认为jQuery支持所有Array
方法,但是不,所以这里是我最初解决方案的工作版本,尽管它有点奇怪,因为我坚持使用相同的方法:
var set; // The array of jQuery objects,
// but make sure it's an Array.
var output = set.pop();
$.each(set, function (_, item) {
return [].push.call(output, [].pop.call(item));
});
如果您的环境支持Array.prototype.reduce()
。
var jQueryCollection = [$("a"), $("div")]
.reduce(function (masterCollection, collection) {
return masterCollection.add(collection);
}, $());
jsFiddle .
你可以这样做:
var $temp = $();
$.each([$("li"), $("li"), $("li")], function(){
$temp.push(this[0]);
})
$temp所有元素在一个jQuery选择器
但是我很好奇是什么让你有不同的jQuery元素数组的这种情况。你知道你可以用逗号选择不同的元素吗?like $("li, ul > li:eq(0), div")
edit正如Guffa指出的,这只添加每个section的第一个元素。.add()
在这里比.push()
更好。
很久以前我也遇到过类似的问题。我有一个巨大的形式,我需要得到每一个input
。因此,我的想法是将每个input
作为jQuery对象,并将其转换为jQuery包装的元素集。我该怎么做呢?这就是你问题的解。
- 首先,您需要创建一个空数组作为jQuery对象,像这样:
- 现在,使用包含选择器表达式的字符串来获取本例中所需的元素:
'form#details :input'
作为jQuery对象。 - 然后使用
.each
方法提取您需要的信息,并将jQuery对象添加到jQuery集包装器:fields = fields.add(input);
let fields = $([]);
。你如何应用于这个问题?
如果你有一个元素列表let elements = [$('#gw_id'), $('#erv_id'), $('#name')];
,你可以用elements
代替$('form#details :input')
;
另一个选择是使用.reduce
vanilla js。在这个let set = $(elements.reduce((acc, cur) => {return acc.concat(cur.get())}, []));
代码片段中,我们使用elements
数组并应用reduce
reduce有4个参数,但我们可以使用前两个accumulator
作为acc
和currentValue
作为cur
,我们还使用箭头函数(=>
)来减少回调。在这个回调中,我们将每个当前值连接到一个新数组中。最后,返回数组被包装成一个jQuery对象$()
。您也可以将elements
替换为$('form#details :input')
。
let fields = $([]);
let elements = [$('#gw_id'), $('#erv_id'), $('#name')];
$(function() {
console.log('List of fields: ');
$('form#details :input').each((index, value) => {
let input = $(value);
let id = input.attr('id');
let type = input.attr('type');
fields = fields.add(input);
if (id && type == 'text') {
console.log('Input: ' + id + ' | Text: ' + type);
}
});
fields.addClass('ui-state-error');
let set = $(elements.reduce((acc, cur) => {
return acc.concat(cur.get())
}, []));
console.log('Set list: ');
set.each((index, value) => {
let input = $(value);
let id = input.attr('id');
let type = input.attr('type');
console.log('Input: ' + id + ' | Text: ' + type);
});
});
.ui-state-error {
background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="details">
<fieldset>
<p>
<label for="gw_id">GW Id</label>
<input type="text" name="gw_id" id="gw_id" value="" class="text ui-widget-content ui-corner-all">
</p>
<p>
<label for="erv_id">ERV Id</label>
<input type="text" name="erv_id" id="erv_id" value="" class="text ui-widget-content ui-corner-all">
</p>
<p>
<label for="name">Name</label>
<input type="text" name="name" id="name" value="" class="text ui-widget-content ui-corner-all">
</p>
<p>
<label for="description">Description</label>
<input type="text" name="description" id="description" value="" class="text ui-widget-content ui-corner-all">
</p>
<input type="hidden" name="no" id="no" value="23" disabled readonly>
<!-- Allow form submission with keyboard without duplicating the dialog button -->
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
</fieldset>
</form>
$('li').each(function(){
$(this).doSomething();
})