NodeList.js macht die Verwendung der nativen DOM-APIs auf einem Array von Nodes so einfach wie jQuery , mit dem Vorteil, dass es mit etwa 4 KB verkleinert extrem klein ist und der Browser eine Abhängigkeit darstellt (das ist der interessanteste Teil) .
Das Erste, was Ihnen auffallen wird, ist, dass ich $$ verwende. Der Grund, warum ich dies für die Auswahl DOM Nodes ausgewählt habe, liegt darin, dass Sie Ihre Devtools öffnen und Folgendes eingeben:
$$ ( 'div' ) ; // Will return a NodeListNodeList.js -Nutzung: HTML bearbeiten wir im Folgenden: < body >
< div id =" container " class =" cont " >
< div class =" child " > </ div >
< div class =" child " > </ div >
< div class =" child " > </ div >
< div class =" child " > </ div >
< div class =" child " > </ div >
< div class =" child " > </ div >
< div class =" child " > </ div >
< div class =" child " > </ div >
< div class =" child " > </ div >
< div class =" child " > </ div >
</ div >
</ body > #container : Jedes der folgenden Elemente gibt ein Array of Nodes zurück (auch bekannt als meine NodeList , nicht die native NodeList des Browsers).
// Method 1
$$ ( '#container div' ) ;
// Method 2
$$ ( '#container' ) . children ;
// Method 3
$$ ( 'div div' ) ;Wenn Sie eine Abfragezeichenfolge übergeben, gibt es ein zweites Argument, das Sie als Bereich übergeben können:
let container = document . getElementById ( 'container' ) ;
$$ ( 'div' , container ) ;Was äquivalent wäre zu:
// Just this doesn't return my NodeList, but the browser's NodeList
container . querySelectorAll ( 'div' ) ; Sie können Knoten als Argumente übergeben:
$$(document, document.body); // returns NodeList
Sie können auch 1 Array von Knoten oder eine NodeList oder eine HTMLCollection übergeben . Wird nicht reduziert, zum Flattern verwenden Sie concat() :
$$([document, document.body]); // returns NodeList
Node abrufen :So würden Sie es normalerweise tun:
let children = document . getElementsByClassName ( 'child' ) ; Jetzt würden Sie Eigenschaften für die untergeordneten Elemente des #container erhalten:
for ( let i = 0 , l = children . length ; i < l ; i ++ ) {
children [ i ] . id ; // ''
children [ i ] . nodeName ; // 'DIV'
children [ i ] . className ; // 'child'
} So würden Sie es mit nodeList.js machen:
$$ ( '.child' ) . id ; // ['', '' ... x10]
$$ ( '.child' ) . nodeName ; // ['DIV', 'DIV' ... x10]
$$ ( '.child' ) . className ; // ['child', 'child' ... x10] Daher würden Sie jede Eigenschaft genauso lesen, wie Sie es mit einem einzelnen Node tun würden :)
Beachten Sie , dass ein Array des Werts der Eigenschaft zurückgegeben wird. Das heißt, Sie können sie anhand des index auswählen und beliebige Array Methods darauf verwenden. Sie werden sehen, wenn Sie zum Schleifenteil gelangen.
node festlegen : Lassen Sie uns weiterhin die Variable children verwenden. So würden Sie also Eigenschaften für die children festlegen:
for ( let i = 0 , l = children . length ; i < l ; i ++ ) {
children [ i ] . className = 'containerChild' ;
children [ i ] . textContent = 'This is some text' ;
} So würden Sie es mit NodeList.js machen:
$$ ( '.child' ) . className = 'containerChild' ;
$$ ( '.child' ) . textContent = 'This is some text' ; node : Ich verwende immer noch die Variable children :
Fügen wir jedem Knoten einen Ereignis-Listener hinzu, auch wenn event delegation am besten wäre, aber für dieses Beispiel:
for ( let i = 0 , l = children . length ; i < l ; i ++ ) {
children [ i ] . addEventListener ( 'click' , function ( ) {
console . log ( this , 'was clicked' ) ;
} ) ;
} So würden Sie es mit NodeList.js machen:
$$ ( '.child' ) . addEventListener ( 'click' , function ( ) {
console . log ( this , 'was clicked' ) ;
} ) ; So cool, oder? Sie können jede Native DOM method verwenden:
Lassen Sie uns einige Attribute festlegen:
$$ ( '.child' ) . setAttribute ( 'class' , 'child div' ) ;
// For setting the class you could just do:
$$ ( '.child' ) . className = 'child div' ;Anklicken der Elemente:
$$ ( '.child' ) . click ( ) ;Entfernen der Elemente:
$$ ( '.child' ) . remove ( ) ; Ich denke, Sie verstehen, worum es geht: Jede Native DOM Method , die jeder Node/Element erbt, können Sie einfach auf der NodeList aufrufen, und sie wird für jedes Element aufgerufen.
Übrigens: Alle DOM Methoden, die normalerweise undefined zurückgeben würden, wenn sie auf einem einzelnen Node aufgerufen werden, geben dieselbe NodeList zurück, um eine Methodenverkettung zu ermöglichen. Wie setAttribute() .
Verwenden einer for-Schleife und ES6 for-of :
Wir werden nur als Beispiele die Knoten aus dem DOM entfernen:
let nodes = $$ ( '.child' ) ;
for ( let i = 0 , l = nodes . length ; i < l ; i ++ ) {
nodes [ i ] . remove ( ) ;
}
for ( let node of nodes ) {
node . remove ( ) ;
} Verwendung von forEach :
// Removes all Nodes and returns same the NodeList to allow method chaining
$$ ( '.child' ) . forEach ( function ( node ) {
node . remove ( ) ;
} ) ;
// But Just do:
$$ ( '.child' ) . remove ( ) ;Durchlaufen der Eigenschaften:
// Returns Array of style objects (CSSStyleDeclaration)
let styles = $$ ( '.child' ) . style ;
for ( let i = 0 , l = styles . length ; i < l ; i ++ ) {
styles [ i ] . color = 'red' ;
}
for ( let style of styles ) {
style . color = 'red' ;
}
styles . forEach ( function ( style ) {
style . color = 'red' ;
} ) ;
// OR loop through the nodes themselves
let nodes = $$ ( '.child' ) ;
for ( let i = 0 , l = nodes . length ; i < l ; i ++ ) {
nodes [ i ] . style . color = 'red' ;
}
for ( let node of nodes ) {
node . style . color = 'red' ;
}
nodes . forEach ( function ( node ) {
node . style . color = 'red' ;
} ) ; // Returns NodeList containing first Node
$$ ( '.child' ) . slice ( 0 , 1 ) ; Die Zuordnung ist einfach. Rufen Sie einfach die Eigenschaft ab, genau wie bei einem einzelnen Knoten
// Returns an Array of the id of each Node in the NodeList
$$ ( '#container' ) . id ;
// No need for
$$ ( '#container' ) . map ( function ( element ) {
return element . id ;
} ) ;
// Map() Checks if Array is fully populated with nodes so returns a NodeList populated with firstChld nodes
$$ ( '#container div' ) . map ( function ( div ) {
return div . firstChild ;
} ) ;
// Maps the firstChild node and removes it, and returns the NodeList of firstChild Nodes
$$ ( '#container' ) . map ( function ( div ) {
return div . firstChild ;
} ) . remove ( ) ;
// Or:
$$ ( '#container' ) . firstChild . remove ( ) ; // Filter out the #container div
$$ ( 'div' ) . filter ( function ( div ) {
return ! div . matches ( '#container' ) ;
} ) ; Ich könnte mir kein besseres Beispiel für die Verwendung von Reduce auf einer NodeList vorstellen (aber es ist möglich).
let unique = $$ ( 'div' ) . reduce ( function ( set , div ) {
set . add ( div . parentElement ) ;
return set ;
} , new Set ( ) ) ; Es gibt auch reduceRight()
Die folgenden concat() -Methoden geben alle eine neue verkettete NodeList zurück (keine Auswirkungen auf die NodeList für die concat() aufgerufen wird)
let divs = $$ ( 'div' ) ;
// Method 1 passing a Node
let divsAndBody = divs . concat ( document . body ) ;
// Method 2 passing an Array of Nodes
let divsAndBody = divs . concat ( [ document . body ] ) ;
// Method 3 passing a NodeList
let divsAndBody = divs . concat ( $$ ( 'body' ) ) ;
// Method 4 passing an Array of NodeList
let divsAndBody = divs . concat ( [ $$ ( 'body' ) ] ) ;
// Method 5 passing multiple Nodes as arguments
let divsAndBodyAndHTML = divs . concat ( document . body , document . documentHTML ) ;
// Method 6 passing multiple Arrays of Nodes as arguments
let divsAndBodyAndHTML = divs . concat ( [ document . body ] , [ document . documentHTML ] ) ;
// Method 7 passing multiple Arrays of NodeList as are arguments
let divsAndBodyAndHTML = divs . concat ( [ $$ ( 'body' ) ] , [ $$ ( 'html' ) ] ) ; Concat() ist rekursiv, sodass Sie ein Array mit der gewünschten Tiefe übergeben können.
Wenn Sie nun etwas übergeben, das kein Node , NodeList , HTMLCollections , Array oder tiefes Array of Arrays ist und etwas anderes als Node , NodeList , HTMLCollections oder Array enthält, wird ein Error ausgegeben .
let divs = $$ ( 'div' ) ;
// Pushes the document.body element, and returns the same NodeList to allow method chaining.
divs . push ( document . body ) ; let divs = $$ ( 'div' ) ;
// Removes last Node in the NodeList and returns a NodeList of the removed Nodes
divs . pop ( ) ; pop() benötigt ein optionales Argument dafür, wie viele Nodes POP sein sollen
// Removes last 2 Nodes in the NodeList and returns a NodeList of the removed Nodes
divs . pop ( 2 ) ; let divs = $$ ( 'div' ) ;
// Removes first Node in the NodeList and returns a NodeList of the removed Nodes
divs . shift ( ) ; shift() benötigt außerdem ein optionales Argument dafür, wie viele Nodes verschoben werden sollen
// Removes first 2 Nodes in the NodeList and returns a NodeList of the removed Nodes
divs . shift ( 2 ) ; let divs = $$ ( 'div' ) ;
// Inserts/unshifts the document.body into the beginning of the NodeList and returns the same NodeList to allow method chaining.
divs . unshift ( document . body ) ; Ersetzen wir das erste Element, das #container wäre, durch document.body
let divs = $$ ( 'div' ) ;
// Removes the first Element, inserts document.body in its place and returns a NodeList of the spliced Nodes
divs . splice ( 0 , 1 , document . body ) ; let divs = $$ ( '.child' ) ;
// Gives each div a data-index attribute
divs . forEach ( function ( div , index ) {
div . dataset . index = index ;
} ) ;
// Reverse the NodeList and returns the same NodeList
divs . sort ( function ( div1 , div2 ) {
return div2 . dataset . index - div1 . dataset . index ;
} ) ; // Returns the same NodeList, but reversed
$$ ( 'div' ) . reverse ( ) ; Ich habe keine join -Methode für NodeLists hinzugefügt, da diese auf den tatsächlichen Knoten nutzlos wäre:
// Returns "[object HTMLDivElement], [object HTMLDivElement] ..."
$$ ( '.child' ) . join ( ) ;Daher können Sie es beim Zuordnen von Eigenschaften weiterhin verwenden:
// Returns "child,child,child,child,child,child,child,child,child,child"
$$ ( '.child' ) . className . join ( ) ; // Returns true if passed Node is included in the NodeList
$$ ( 'body' ) . includes ( document . body ) ; // Returns body element: <body>
$$ ( 'body' ) . find ( function ( el ) {
return el === el ;
} ) ; // Returns 0
$$ ( 'body' ) . findIndex ( function ( el ) {
return el === el ;
} ) ; Möglicherweise wird es in Zukunft DOM -Methoden geben, die denselben Namen wie die von Array.prototype haben, oder Sie möchten die NodeList einfach in ein Array konvertieren, damit Sie sie als natives Array verwenden können :
asArray Eigenschaft $$ ( 'body' ) . asArray ; // returns Array
$$ ( 'body' ) . asArray . forEach ( function ( ) { ... } ) ; // uses native Array method therefore you cannot chain Ok, wie wäre es nun mit dem Umgang mit Elementen, die einzigartige Eigenschaften haben? Wie HTMLAnchorElement(s) verfügen sie über die href Eigenschaft, die nicht von HTMLElement geerbt wird. In diesem Beispiel gibt es keine HTMLAnchorElements , aber hier erfahren Sie, wie Sie damit umgehen.
// Returns undefined because it's a unique property that every element does not inherit
$$ ( 'a' ) . href
// Returns an Array of href values
$$ ( 'a' ) . get ( 'href' ) ; Get() kann auch für ein Array von Eigenschaften verwendet werden:
// Returns an Array of the value of each node.style.color
$$ ( '.child' ) . style . get ( 'color' ) ; // Sets the href property of each Node in NodeList
$$ ( 'a' ) . set ( 'href' , 'https://www.example.com/' ) ; set() legt nur die Eigenschaften der Nodes fest, deren Eigenschaften nicht undefiniert sind:
$$ ( 'div, a' ) . set ( 'href' , 'https://www.example.com/' ) ; href wird nur für die <a> -Elemente und nicht für die <div> -Elemente festgelegt
set() kann auch für ein Array von Eigenschaften verwendet werden:
// Sets each element's color to red and returns the Array of styles back
$$ ( '.child' ) . style . set ( 'color' , 'red' ) ;Sie können auch mehrere Eigenschaften festlegen:
$$ ( '.child' ) . set ( {
textContent : 'Hello World' ,
className : 'class1 class2'
} ) ;Das Gleiche gilt für zugeordnete Eigenschaften:
$$ ( '.child' ) . style . set ( {
color : 'red' ,
background : 'black'
} ) ;Denken Sie daran, dass Sie Folgendes verketten können:
$$ ( '.child' ) . set ( {
textContent : 'Hello World' ,
className : 'class1 class2'
} ) . style . set ( {
color : 'red' ,
background : 'black'
} ) ; Es gibt Methoden, die nur für bestimmte Elemente gelten. So würden Sie diese Methoden aufrufen:
$$ ( 'video' ) . call ( 'pause' ) ;Oder Sie können einfach die Elemente durchlaufen und die Methoden aufrufen
Wie wäre es mit der Übergabe von Argumenten:
// Returns Array of `CanvasRenderingContext2D`
$$ ( 'canvas' ) . call ( 'getContext' , '2d' ) ; Wenn die für eines der Elemente aufgerufene Methode etwas zurückgibt, wird von call() ein Array dieser zurückgegebenen Elemente zurückgegeben, andernfalls wird die NodeList zurückgegeben, um eine Methodenverkettung zu ermöglichen.
Die native item(index) -Methode des Browsers macht dasselbe wie NodeList[index] aber in meinem gibt sie diesen Node als meine NodeList zurück (Wenn Sie jQuery kennen, ist es dasselbe wie eq() -Methode von jQuery)
// returns the <html> element
$$ ( 'html, body' ) [ 0 ] ;
// returns my NodeList [<html>]
$$ ( 'html, body' ) . item ( 0 ) ; Auf diese Weise können Sie weiterhin dieselben Eigenschaften/Methoden meiner NodeList verwenden, anstatt den einen Node slice zu müssen
owner : Die Eigentümereigenschaft gibt Ihnen lediglich die NodeList zurück, aus der die Eigenschaft zugeordnet wurde:
var elms = $$ ( '.child' ) ;
elms . style . owner === elms ; // trueDamit ich alles Mögliche machen kann:
Denken Sie daran, dass style Zuordnungsstil ein Array von CSSStyleDeclarations zurückgibt
$$ ( '.child' ) . style ; Dadurch erhalten Sie die NodeList zurück, aus der der style zugeordnet wurde:
var childs = $$ ( '.child' ) ;
childs . style . owner === childs ; // true Wenn Sie wissen, dass jQuery mit seiner prevObj -Eigenschaft identisch ist
$$ . NL . myMethod = function ( ) {
// You'll have to write your own loop here if you want to call this on each Node or use:
this . forEach ( function ( node ) {
// do something with each node
} ) ;
}| Browser | Version |
|---|---|
| FireFox | 6+ |
| Safari | 5.0.5+ |
| Chrom | 6+ |
| IE | 9+ |
| Oper | 11+ |
Achtung: Sie müssen sich darüber im Klaren sein, dass meine Bibliothek vom Browser abhängt, den sie ausführt (was großartig ist, da sie automatisch aktualisiert wird, wenn der Browser das DOM mit neuen Eigenschaften/Methoden aktualisiert). Das heißt: Nehmen wir an, die hidden Eigenschaft existiert im Browser nicht DOM API ist nicht möglich: $$('.child').hidden = true;