Core points
-
NodeList.js, as an alternative to DOM operation for jQuery, offers similar functionality, but is smaller (4k after compression) and takes advantage of improvements to the native browser API.
-
Unlike jQuery, NodeList.js treats node arrays as single nodes, enabling cleaner code and easier NodeList object operations.
-
NodeList.js contains special methods for setting and getting attributes, calling element-specific methods, and accessing nodes in NodeList, and the
prevObject
attribute equivalent to jQuery'sowner
attribute. -
NodeList.js is compatible with mainstream browsers after a specific version (Firefox 6, Safari 5.0.5, Chrome 6, IE 9, Opera 11.6), and is automatically updated to include new methods/properties added by the browser.
p.tip { background-color: rgba(128,128,128,0.05); border-top-right-radius: 5px; border-bottom-right-radius: 5px; padding: 15px 20px; border-left: 10px solid rgba(128,128,128,0.075); }
In recent years, jQuery has become the de facto JavaScript library on the Web. It removes a lot of cross-browser inconsistencies and adds a layer of popular syntactic sugar to client scripts. One of its main pain points in abstraction processing is DOM operations, but since the advent of jQuery, native browser APIs have been significantly improved, and the concept of "you probably don't need jQuery" has become popular.
The reasons are as follows:
- jQuery contains many features that you don't need or use (and therefore it is unnecessary to be huge).
- jQuery takes on too many functions for too many people. Generally, smaller libraries can do some tasks better.
- In terms of DOM operations, the browser API can now perform most of the functions of jQuery.
- The browser API is now more synchronized, for example using
addEventListener
instead ofattachEvent
.
What is the problem?
The problem is that using native (or pure) JavaScript for DOM can be troublesome compared to jQuery. This is because you have to write more redundant code and handle the browser's useless NodeList.
First, let's take a look at MDN's definition of NodeList:
TheNodeList object is a collection of nodes, such as those returned by the Node.childNodes
and document.querySelectorAll
methods.
There are sometimes dynamics NodeList (which can be confusing):
In some cases, NodeList is a dynamic collection, which means changes in the DOM are reflected in the collection. For example, Node.childNodes
is dynamic.
This can be a problem because you can't tell which are dynamic and which are static. Unless you remove each node from the NodeList and then check if the NodeList is empty. If empty, you have a dynamic NodeList (it's just a bad idea).
In addition, the browser does not provide any useful methods to manipulate these NodeList objects.
For example, unfortunately, it is not possible to loop through nodes using forEach
var nodes = document.querySelectorAll('div'); nodes.forEach(function(node) { // do something }); // 錯誤:nodes.forEach 不是函數(shù)Therefore, you have to do the following:
var nodes = document.querySelectorAll('div'); for(var i = 0, l = nodes.length; i < l; i++) { // do something with nodes[i] }Or even only use "hack":
[].forEach.call(document.querySelectorAll('div'), function(node) { // do something });The browser's native NodeList has only one method:
. It returns a node from NodeList via index. When we can access the node like we use an array (using item
), it is completely useless: array[index]
var nodes = document.querySelectorAll('div'); nodes.item(0) === nodes[0]; // trueThis is where NodeList.js comes in - making it as easy to operate a DOM using a browser native API as using jQuery, but only requires 4k compression size.
Solution
I created NodeList.js because I've been using native DOM APIs, but want to make them more concise, thus reducing a lot of redundancy when writing code (such as for loops).
NodeList.js is a wrapper for the native DOM API that allows you to manipulate arrays of nodes (i.e. my NodeList) as if it were a single node. This gives you more functionality than the browser native NodeList object.
If you think this is good, get a copy of NodeList.js from the official GitHub repository and continue reading the rest of this tutorial.
Usage:
Selecting a DOM node is simple:
// Return to my NodeList
$$(selector);
This method is used in the background
. querySelectorAll(selector)
Glad you asked this question. Let's compare native JS, jQuery, and NodeList.js.
Suppose we have three buttons:
Let's change the text of each button to "Click Me":
Native JS:
var buttons = document.querySelectorAll('button'); // 返回瀏覽器無用的 NodeList for(var i = 0, l = buttons.length; i < l; i++) { buttons[i].textContent = 'Click Me'; }
jQuery:
$('button').text('Click Me');
NodeList.js:
$$('button').textContent = 'Click Me';
Here, we see that NodeList.js can effectively treat NodeList as a single node. That is, we reference a NodeList and set its
property to "Click Me". NodeList.js then performs this for each node in the NodeList. Very clever, right? textContent
$$('button').set('textContent', 'Click Me');
Now, let's add a click event listener to each button:
Native JS:
var buttons = document.querySelectorAll('button'); // 返回瀏覽器無用的 NodeList for(var i = 0, l = buttons.length; i < l; i++) { buttons[i].addEventListener('click', function() { this.classList.add('clicked'); }); }
jQuery:
$('button').on('click', function() { $(this).addClass('click'); // 或?qū)?jQuery 與原生混合使用 `classList`: this.classList.add('clicked'); });
NodeList.js:
$$('button').addEventListener('click', function() { this.classList.add('clicked'); });
Okay, so the
method of jQuery is quite good. My library uses the browser's native DOM API (hence on
), but that doesn't prevent us from creating an alias for the method: addEventListener
$$.NL.on = $$.NL.addEventListener; $$('button').on('click', function() { this.classList.add('clicked'); });
Not bad! This demonstrates how we add our own method:
var nodes = document.querySelectorAll('div'); nodes.forEach(function(node) { // do something }); // 錯誤:nodes.forEach 不是函數(shù)
NodeList.js Support for array methods
NodeList.js does inherit from Array.prototype
, but not directly, because some methods have been changed, so it makes sense to use them with NodeList (array of nodes).
push
and unshift
For example: push
and unshift
methods can only take nodes as parameters, otherwise an error will be thrown:
var nodes = document.querySelectorAll('div'); for(var i = 0, l = nodes.length; i < l; i++) { // do something with nodes[i] }
So both push
and unshift
return NodeList to allow method chaining, meaning it is different from JavaScript's native Array#push
or Array#unshift
methods, which accept anything and return the array's New length. If we do want the length of NodeList, we just need to use the length
property.
These two methods, like JavaScript's native array method, change the NodeList.
concat
concat
The method accepts the following as parameters:
[].forEach.call(document.querySelectorAll('div'), function(node) { // do something });
concat
is a recursive method, so these arrays can be as deep as we would like to be and will be flattened. However, if any element in the passed array is not a node, NodeList, or HTMLCollection, it will throw an error.
concat
Returns a new NodeList, just like the Array#concat
method of javascript.
pop
, shift
, map
, slice
, filter
,
,
Both the pop
shift
and Array#pop
methods can take optional parameters, indicating how many nodes to pop or shift from the NodeList. Unlike JavaScript's native Array#shift
or
map
If each mapped value is a node, the
The slice
filter
and
Array.prototype
Since NodeList.js does not inherit directly from Array.prototype
, if you add a method to
You can view the remaining array methods of NodeList.js here.
Special Method
owner
NodeList.js has four unique methods, and a property called prevObject
, which is equivalent to the
get
set
and
Method:
href
Some elements have attributes specific to elements of that type (for example, the $$('a').href
attribute on the anchor tag). This is why get
will return undefined - because it is not a property inherited by every element in NodeList. This is how we use the
var nodes = document.querySelectorAll('div'); nodes.forEach(function(node) { // do something }); // 錯誤:nodes.forEach 不是函數(shù)The
set
method can be used to set these properties for each element:
var nodes = document.querySelectorAll('div'); for(var i = 0, l = nodes.length; i < l; i++) { // do something with nodes[i] }
set
also returns NodeList to allow method chaining. We can use it in textContent
etc. (both equivalent):
[].forEach.call(document.querySelectorAll('div'), function(node) { // do something });
We can also set multiple properties in one call:
var nodes = document.querySelectorAll('div'); nodes.item(0) === nodes[0]; // true
All the above operations can be done using any attribute, for example style
:
var buttons = document.querySelectorAll('button'); // 返回瀏覽器無用的 NodeList for(var i = 0, l = buttons.length; i < l; i++) { buttons[i].textContent = 'Click Me'; }
call
Method
The call
method allows you to call element-specific methods (for example, pause
on a video element):
$('button').text('Click Me');
item
Method
The item
method is equivalent to the eq
method of jQuery. It returns a NodeList which contains only the nodes passing the index:
$$('button').textContent = 'Click Me';
owner
Attributes
The owner
attribute is equivalent to the prevObject
of jQuery.
$$('button').set('textContent', 'Click Me');
btns.style
returns a style array, while owner
will return the NodeList mapped by style
.
NodeList.js Compatibility
My library is compatible with all major new browsers as described below.
Browser version
For a compression size of about 4k you get all the above and more, which you can learn about in the GitHub repository of NodeList.js.
Since NodeList.js uses a browser as a dependency, no upgrade is required. Whenever the browser adds new methods/attributes to the DOM element, you can use these methods/attributes automatically via NodeList.js. All of this means that the only deprecation you need to worry about is the browser removal method. These are usually very low usage methods because we can't break the web.
So what do you think? Would you consider using this library? Are any important features missing? I'd love to hear your comments in the comments below.
Frequently Asked Questions about DOM Operations with NodeList.js
What is the difference between NodeList and HTMLCollection?
NodeList and HTMLCollection are both node collections. The main difference between them is that NodeList can contain any node type, while HTMLCollection is a collection of element nodes. HTMLCollection is also dynamic, meaning it will be updated automatically when the document structure changes. NodeList, on the other hand, is static and does not update to reflect changes in the document.
How to convert NodeList to an array?
You can convert NodeList to an array using the
method or the expand operator. Here's how to do it:
var nodes = document.querySelectorAll('div'); nodes.forEach(function(node) { // do something }); // 錯誤:nodes.forEach 不是函數(shù)
Why does the jQuery selector return prevObject instead of a normal element?
jQuery's chaining mechanism works by storing previous objects before making changes. This allows you to use the .end()
method to restore to your previous state. If you want to get the actual DOM element, you can use the .get()
method or array notation.
How to loop through NodeList?
You can loop through the NodeList using the for loop, for...of loop, or forEach()
method. Here is an example using a for loop:
var nodes = document.querySelectorAll('div'); for(var i = 0, l = nodes.length; i < l; i++) { // do something with nodes[i] }
What is the use of the .prev() method in jQuery?
The .prev()
method in jQuery is used to select the selected element immediately next to the previous sibling. If a selector is provided, the previous sibling element is retrieved only when the selector is matched.
Is jQuery still relevant in 2022?
While jQuery was a game-changer at launch, the modern JavaScript ecosystem has changed significantly. Many of the features that make jQuery popular are now built into JavaScript itself. However, jQuery is still widely used and maintained, and it may be a good choice for some projects.
How to select a specific node from NodeList?
You can select a specific node from NodeList using the array notation or the item()
method. Here's how to do it:
[].forEach.call(document.querySelectorAll('div'), function(node) { // do something });
Can I use map, filter, and reduce methods on NodeList?
NodeList is not an array, so it does not have methods like map, filter, and reduce. However, you can convert NodeList to an array and then use these methods.
What is the difference between querySelector and querySelectorAll?
querySelector
Returns the first element in the document that matches the specified CSS selector, and querySelectorAll
returns the NodeList of all elements that match the CSS selector.
How to check if NodeList is empty?
You can check if NodeList is empty by checking its length
property. If the length is 0, NodeList is empty. Here's how to do it:
var nodes = document.querySelectorAll('div'); nodes.item(0) === nodes[0]; // true
The above is the detailed content of Lose the jQuery Bloat -. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Java and JavaScript are different programming languages, each suitable for different application scenarios. Java is used for large enterprise and mobile application development, while JavaScript is mainly used for web page development.

JavaScriptcommentsareessentialformaintaining,reading,andguidingcodeexecution.1)Single-linecommentsareusedforquickexplanations.2)Multi-linecommentsexplaincomplexlogicorprovidedetaileddocumentation.3)Inlinecommentsclarifyspecificpartsofcode.Bestpractic

The following points should be noted when processing dates and time in JavaScript: 1. There are many ways to create Date objects. It is recommended to use ISO format strings to ensure compatibility; 2. Get and set time information can be obtained and set methods, and note that the month starts from 0; 3. Manually formatting dates requires strings, and third-party libraries can also be used; 4. It is recommended to use libraries that support time zones, such as Luxon. Mastering these key points can effectively avoid common mistakes.

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScriptispreferredforwebdevelopment,whileJavaisbetterforlarge-scalebackendsystemsandAndroidapps.1)JavaScriptexcelsincreatinginteractivewebexperienceswithitsdynamicnatureandDOMmanipulation.2)Javaoffersstrongtypingandobject-orientedfeatures,idealfor

Event capture and bubble are two stages of event propagation in DOM. Capture is from the top layer to the target element, and bubble is from the target element to the top layer. 1. Event capture is implemented by setting the useCapture parameter of addEventListener to true; 2. Event bubble is the default behavior, useCapture is set to false or omitted; 3. Event propagation can be used to prevent event propagation; 4. Event bubbling supports event delegation to improve dynamic content processing efficiency; 5. Capture can be used to intercept events in advance, such as logging or error processing. Understanding these two phases helps to accurately control the timing and how JavaScript responds to user operations.

JavaScripthassevenfundamentaldatatypes:number,string,boolean,undefined,null,object,andsymbol.1)Numbersuseadouble-precisionformat,usefulforwidevaluerangesbutbecautiouswithfloating-pointarithmetic.2)Stringsareimmutable,useefficientconcatenationmethodsf

If JavaScript applications load slowly and have poor performance, the problem is that the payload is too large. Solutions include: 1. Use code splitting (CodeSplitting), split the large bundle into multiple small files through React.lazy() or build tools, and load it as needed to reduce the first download; 2. Remove unused code (TreeShaking), use the ES6 module mechanism to clear "dead code" to ensure that the introduced libraries support this feature; 3. Compress and merge resource files, enable Gzip/Brotli and Terser to compress JS, reasonably merge files and optimize static resources; 4. Replace heavy-duty dependencies and choose lightweight libraries such as day.js and fetch
