Поверните массив элементов jQuery в jQuery, завернутый в набор элементов
Есть ли элегантный способ превращения [$(div), $(span), $(li)]
в $(div, span, li)
?
Мне нужен набор элементов, состоящий из jQuery, вместо массива элементов jQuery. Я хотел бы сделать это как можно меньше строк кода и с минимальным (если есть) циклом.
Изменить: Для тех, кого вы путаете по этому вопросу, этот код копируется и вставляется из firebug с помощью console.log в массив элементов, у которых уже выбран.
Ответы
Ответ 1
Функция jQuery map()
идеально подходит для перестройки массивов и/или коллекций jQuery.
Итак, учитывая массив, заданный так:
var arrayOfJQ_Objects = [$("div"), $("span"), $("li")];
Эта одна строка кода - это все, что вам нужно (Посмотрите на действие в jsFiddle):
$(arrayOfJQ_Objects).map (function () {return this.toArray(); } );
Результирующее отображение этой консоли в Firebug:
jQuery(div, span, li)
Ссылка, также, функция jQuery .toArray()
.
Ответ 2
Если вы действительно имеете в виду, как конвертировать:
[$(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() }));
Ответ 3
Вы можете использовать метод add
для копирования элементов в объект jQuery в другой. Это скопирует все элементы из каждого из объектов jQuery в массиве source
в объект 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());
.)
Ответ 4
Немного более кратким, чем принятый ответ, можно использовать $.fn.toArray
в качестве аргумента, переданного в $.fn.map
:
var list = [$('<a>'), $('<b>'), $('<i>')];
$(list).map($.fn.toArray);
Или возможно (это действительно уступает, но имеет только один вызов функции в вашем коде):
$.fn.map.call(list, $.fn.toArray);
Ответ 5
Допустим, у вас есть массив элементов jQuery:
let elementList = [$("selector1"), $("selector2"), $("selector3"), ...];
Вы можете просто использовать функцию jQuery ($()
) непосредственно в массиве, который будет возвращать набор jQuery:
let jQuerySetOfElements = $(elementList);
Ответ 6
Изменить. Я думал, что jQuery поддерживает все методы Array
, но нет, поэтому здесь рабочая версия моего первоначального решения, хотя и немного странная, поскольку я придерживаюсь тех же методов:
var set; // The array of jQuery objects,
// but make sure it an Array.
var output = set.pop();
$.each(set, function (_, item) {
return [].push.call(output, [].pop.call(item));
});
Ответ 7
Чтобы добавить отдельный элемент:
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(); } ));
Ответ 8
Если Array.prototype.reduce()
поддерживается в вашей среде.
var jQueryCollection = [$("a"), $("div")]
.reduce(function (masterCollection, collection) {
return masterCollection.add(collection);
}, $());
jsFiddle.
Ответ 9
вы можете сделать что-то вроде этого:
var $temp = $();
$.each([$("li"), $("li"), $("li")], function(){
$temp.push(this[0]);
})
$temp все ваши элементы в одном селекторе jQuery
Но мне любопытно, что привело вас к этой ситуации с массивом различных элементов jQuery. Вы знаете, что вы можете выбрать разные элементы, используя запятую? как $("li, ul > li:eq(0), div")
отредактируйте, как указал Гуффа, это добавляет только первый элемент каждого раздела. .add()
- лучший выбор, тогда .push()
здесь.
Ответ 10
У меня похожая проблема давно. У меня огромная форма, и мне нужно получить каждый input
. Итак, моя идея состояла в том, чтобы взять каждый input
как объект jQuery и превратить его в упакованный набор элементов jQuery. Как я могу это сделать? Ну, это решение вашего вопроса.
- Сначала вам нужно создать пустой массив в виде объекта jQuery, например:
let fields = $([]);
, - Теперь используйте строку, содержащую выражение селектора, чтобы получить элементы, которые вам нужны в этом примере:
'form#details :input'
качестве объектов jQuery. - Затем используйте метод
.each
для извлечения необходимой информации и добавьте объект jQuery в упаковщик набора jQuery: fields = fields.add(input);
Как вы относитесь к этому вопросу?
Если у вас есть список элементов, то let elements = [$('#gw_id'), $('#erv_id'), $('#name')];
вы можете заменить $('form#details :input')
на elements
;
Другой альтернативой является использование .reduce
vanilla js. в этом let set = $(elements.reduce((acc, cur) => {return acc.concat(cur.get())}, []));
фрагмент кода мы используем массив elements
и применять reduce
снижения имеет 4 параметра, но мы можем использовать первые два, которые являются accumulator
в acc
и currentValue
как cur
также мы используем функцию Arrow (=>
), чтобы уменьшить обратный вызов. В этом обратном вызове мы объединяем каждое текущее значение в новом массиве. Наконец, возвращаемый массив помещается в объект 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>
Ответ 11
$('li').each(function(){
$(this).doSomething();
})