5 ms·
>>> My JS is a bit rusty, but I remember that in JQuery I could do: $("some selector").do_things() And "do_things" would be done on all matching elements. ---
by 52-6F-62 9y ago
>>> My JS is a bit rusty, but I remember that in JQuery I could do:
$("some selector").do_things()
And "do_things" would be done on all matching elements.
---
jQuery selectors were matched in native JS by `document.querySelector()` and `document.querySelectorAll()`
Pretty sure `querySelectorAll()` operates quite the same as jQuery's selector which returns an array of element objects that you can perform actions upon. The primary difference being that you'll have to run the actions in a loop over the array if you want to perform them over the entire selection. Eg:
let elements = document.querySelectorAll('li');
for(let i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', e => {
console.log(`This element is ${elements[i]}`);
});
}
You could write a helper in a few lines to handle that throughout your codebase if it's commonly used.
- yunyu 9y agoYou can wrap that in Array.from() to take advantage of foreach, filter, etc..
- ccheney 9y agoThis is how i've been doing it: const elements = document.querySelectorAll('li'); [...elements].forEach((element) => element.addEventListener('click', this.onClickHandler));
- 52-6F-62 9y agoThis is a much more elegant solution. Thanks.
- loganfsmyth 9y agoIt's even easier now. `.forEach` on `NodeList` is standard https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach https://developer.mozilla.org/en-US/docs/Web/API/NodeList/fo..., so all you need to do is load a polyfill for that.
- shortstuffsushi 9y agoWhy do you need the [ ... elements ] -- can't you call foreach off elements directly? Is it not an array?
- humblebee 9y agoIt's not an array, but in recent versions of browser it does support `forEach` and some others. https://developer.mozilla.org/en-US/docs/Web/API/NodeList https://developer.mozilla.org/en-US/docs/Web/API/NodeList
- diggan 9y agoNo, it returns a NodeList, not an array. But, forEach exists on NodeList, but map and reduce does not (together with all the rest of the array functions).
- shortstuffsushi 9y agoHuh, TIL I guess. I've only barely messed with that, and it most have just been on "recent enough" versions to support array functions.
- Xcelerate 9y agoAnd this is why JavaScript is one of my least favorite languages. Is there a website that stays up-to-date with a brief summary of all this nonsense? I haven't programmed in JavaScript in 4 years but am needing to relearn it again for a project, and searching Google for "iterating over elements" in JavaScript returns 57 different techniques, all considered "the best way" at some different point in time over the last few years, and all with varying levels of browser support. Looping/filtering over things should just not be this convoluted of a process...
- shortstuffsushi 9y agoI think that the Mozilla Dev docs would probably be useful to you, or at least that's what I always end up going to -- https://developer.mozilla.org/en-US/ https://developer.mozilla.org/en-US/
- wanda 9y agoThis works too: var elements = document.querySelectorAll('li'); var arr_elements = [].slice.call(elements);
- dmitriid 9y ago> jQuery selectors were matched in native JS by `document.querySelector()` and `document.querySelectorAll()` Funny how the first words of your statement are completely negated by the last half of your statement. jQuery: $(<any selector>).anyfunction This will work regardless of the number of elements returned by the selector: 0, 1, or any number. The so called matching `document.querySelector()` and `document.querySelectorAll()` cannot come even close to the ease of use of jQuery's selectors. `document.querySelector` returns one element only. It will be the first element matched, even if you have more. `document.querySelectorAll` returns a pseudo-array of elements (in reality a NodeList) that lacks most of functionality of arrays, and you cannot apply any DOM functions to it without iterating through the entire list. jQuery came out in 2006. It took w3c several years after that to come up with something resembling jQuery's selection function. 11 years later there's still not a single method in the entire DOM API that comes even close to jQuery's simplicity and expressiveness.
- 52-6F-62 9y agoI'm not sure how you took my remarks as a criticism of jQuery, as it's likely because of them that selectors were approached from said angle at all. Anyway it's pretty simple to emulate the jQuery selectors' syntax elegance. eg. from a link I posted below. This would produce similar results to jQuery selectors (minus backwards compatibility for older versions of IE). -- Note if you try to use vanilla JS methods on a jQuery-selected element you will have to target which of the selected elements you want to act upon. It will return undefined for the selected element and throw an error if you try to, for instance `$('p').innerHTML = 'something';`: class DOM { constructor ( selector ) { let elements = document.querySelectorAll(selector); this.length = elements.length; Object.assign(this, elements); } each ( callback ) { for (let el of Array.from(this) ) { callback.call(el); } return this; } on( eventType, callback ) { this.each(function() { this.addEventListener( eventType, callback, false ); }); } } let $ = s => new DOM(s); $('#something').on('click', e => console.log(`Hello, event: ${e}`) );
- dmitriid 9y ago> I'm not sure how you took my remarks as a criticism of jQuery I was replying to this statement: "jQuery selectors were matched in native JS by `document.querySelector()` and `document.querySelectorAll()`" > it's likely because of them that selectors were approached from said angle at all. This is true :) > This would produce similar results to jQuery selectors (minus backwards compatibility for older versions of IE). It doesn't though. There are many more useful methods in jQuery, and you will eventually need to re-implement many of them. (Even such simple once as `.class()` or `.toggleClass()`, or `.attr()`, or `append()`, and many others). It's easier to just go with jQuery :)