Maison >interface Web >js tutoriel >TreeWalker : un guide pratique de la traversée du DOM
Récemment, j'ai commencé à travailler sur une nouvelle extension Chrome pendant mon temps libre et dans la recherche sur la façon de gérer certaines fonctionnalités, j'ai commencé à découvrir de plus en plus de fonctionnalités dont JS dispose pour gérer le DOM du page.
Étant donné qu'un nombre écrasant de personnes utilisant JS l'utilisent uniquement via un framework, cela constituerait un sujet intéressant pour une série d'articles courts permettant aux gens d'en apprendre un peu plus sur les technologies sous-jacentes sur lesquelles les frameworks sur lesquels ils s'appuient sont utilise réellement.
Nous sommes tous passés par là : vous devez trouver des éléments spécifiques dans le DOM, mais querySelector et getElementsBy* ne suffisent pas vraiment. Peut-être avez-vous besoin de trouver tous les nœuds de texte contenant une phrase spécifique, ou souhaitez-vous parcourir des éléments correspondant à certaines conditions tout en en ignorant d'autres. Entrez TreeWalker - une API de traversée DOM puissante mais souvent négligée.
TreeWalker est une interface DOM qui vous permet de parcourir et de filtrer efficacement les nœuds DOM. Considérez-le comme une alternative plus puissante et plus flexible aux méthodes telles que querySelector. Alors que querySelector vous donne des éléments correspondant à un sélecteur CSS, TreeWalker vous permet :
Commençons par un exemple basique :
const walker = document.createTreeWalker( document.body, // Root node to start traversal NodeFilter.SHOW_TEXT, // Only show text nodes { acceptNode: function(node) { // Only accept text nodes that aren't empty return node.textContent.trim().length > 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; } } );
Les trois paramètres sont :
Voici quelque chose que vous utiliserez réellement : rechercher et remplacer du texte tout en préservant la structure HTML.
function replaceText(root, search, replace) { const walker = document.createTreeWalker( root, NodeFilter.SHOW_TEXT, { acceptNode: function(node) { return node.textContent.includes(search) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; } } ); let node; while (node = walker.nextNode()) { node.textContent = node.textContent.replace(search, replace); } } // Usage replaceText(document.body, 'old text', 'new text');
C'est beaucoup plus efficace que d'utiliser innerHTML et ne brisera pas les écouteurs d'événements ni ne formera de valeurs d'entrée.
Besoin de trouver des éléments correspondant à des conditions complexes ? TreeWalker a ce qu'il vous faut. Construisons quelque chose de plus complexe : disons que vous devez trouver tous les éléments éléments contenant du texte spécifique, mais uniquement s'ils se trouvent à l'intérieur de Cela correspondrait : ✅ Correspondra : TreeWalker brille quand : Bonne nouvelle pour les utilisateurs de TypeScript : les types sont intégrés : TreeWalker est l'une de ces API que, une fois que vous en aurez connaissance, vous vous retrouverez à utiliser plus souvent que vous ne le pensez. Il est particulièrement utile pour créer des outils d'accessibilité, des systèmes de gestion de contenu ou toute application nécessitant d'analyser ou de modifier le contenu DOM par programme. Bien que cela puisse paraître complexe au premier abord, la puissance et la flexibilité de TreeWalker valent la peine de l'ajouter à votre boîte à outils. La prochaine fois que vous vous retrouverez à écrire une fonction de traversée récursive du DOM, demandez-vous si TreeWalker pourrait être une meilleure solution. P.S. Si vous êtes arrivé jusqu'ici, voici un conseil de pro : combinez TreeWalker avec MutationObserver pour créer de puissants outils de surveillance DOM. Mais c'est un sujet pour un autre article... ? Si vous avez trouvé cet article utile, n'hésitez pas à aimer et à suivre pour plus de trucs et astuces JavaScript. Photo de couverture par Branko Stancevic sur Unsplash Photo de couverture par Branko Stancevic sur Unsplash Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!
function findElementsByComplexCondition(root, config) {
const results = [];
const walker = document.createTreeWalker(
root,
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
{
acceptNode: function(node) {
// Skip nodes we don't care about early
if (node.nodeType === Node.ELEMENT_NODE &&
node.tagName === 'BUTTON') {
return NodeFilter.FILTER_REJECT; // Skip button and its contents
}
// Check for matching span elements
if (node.nodeType === Node.ELEMENT_NODE &&
node.tagName === 'SPAN') {
// Check if parent is a div with required class
const parent = node.parentElement;
if (!parent ||
parent.tagName !== 'DIV' ||
!parent.classList.contains(config.parentClass)) {
return NodeFilter.FILTER_SKIP;
}
// Check if span contains the required text
const text = node.textContent?.toLowerCase() || '';
if (!text.includes(config.searchText.toLowerCase())) {
return NodeFilter.FILTER_SKIP;
}
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_SKIP;
}
}
);
let node;
while (node = walker.nextNode()) {
results.push(node);
}
return results;
}
<div>
<p>❌ Won't match all of the following:<br>
</p>
<pre class="brush:php;toolbar:false"><div>
<p>[Rest of code examples...]</p>
<h2>
The Swiss Army Knife of DOM Traversal
</h2>
<p>TreeWalker isn't limited to forward traversal. You can move in any direction:<br>
</p>
<pre class="brush:php;toolbar:false">// Move to next node
walker.nextNode();
// Move to previous node
walker.previousNode();
// Move to first child
walker.firstChild();
// Move to last child
walker.lastChild();
// Move to parent
walker.parentNode();
Quand devriez-vous utiliser TreeWalker ?
Prise en charge du script dactylographié
const walker = document.createTreeWalker(
document.body, // Root node to start traversal
NodeFilter.SHOW_TEXT, // Only show text nodes
{
acceptNode: function(node) {
// Only accept text nodes that aren't empty
return node.textContent.trim().length > 0
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_REJECT;
}
}
);
Pensées finales
Photo de chat par Jan Gustavsson sur Unsplash