I often need to convert the result of a selector to an array of JQuery objects so that I can for..of
on them, I end up doing a lot of:
const arr = $.makeArray($(selector)).map(el => $(el));
(I usually have a function doing this internally)
I then do things like:
for (let jel of arr) jel.toggle(false);
Does JQuery have a better/builtin way to create such arr
?
CodePudding user response:
As Kevin points out, in that specific case, there's no reason for the loop. toggle
operates on the entire collection, so simply $("selector").toggle(false)
(or $("selector").hide();
). This is one of the great things about jQuery, it's set-based (for setters and actions; not for getters).
But if the goal is to get an array of individual jQuery wrappers around every element in a jQuery object, your version seems fine, but it can be slightly simpler:
const arr = Array.from($(selector), el => $(el));
That uses the mapping callback on Array.from
, avoiding an unnecessary intermediate array:
const wrappers = Array.from($(".a"), (el) => $(el));
for (const wrapper of wrappers) {
console.log(wrapper.text());
}
<div >1</div>
<div >2</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If the goal is just to get an iterable (rather than an array) that can be used with for-of
and anything else that understands iterables, wrapping each individual element in a jQuery wrapper, you could add a function (plugin) to do that using a generator function:
// The plugin
(($) => {
jQuery.fn.wrapped = function*() {
for (let n = 0; n < this.length; n) {
yield $(this[n]);
}
};
})(jQuery);
// Using it
for (const wrapper of $(".a").wrapped()) {
console.log(wrapper.text());
}
<div >1</div>
<div >2</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Or as a static method inspired by your comment below:
// The plugin
(($) => {
$.iterable = function*(...args) {
const wrapper = $(...args);
for (let n = 0; n < wrapper.length; n) {
yield $(wrapper[n]);
}
};
})(jQuery);
// Using it
for (const wrapper of $.iterable(".a")) {
console.log(wrapper.text());
}
<div >1</div>
<div >2</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>