Мне нужна помощь с использованием рекурсии для навигации по каждому элементу в DOM - PullRequest
0 голосов
/ 10 февраля 2020

Мне нужно использовать рекурсию для навигации по каждому элементу в DOM и для каждого элемента тела определить, является ли он элементом элемента. Если это так, мне нужно добавить дочерний узел к нему. Мне нужно использовать JavaScript для этого задания. Вот что у меня есть в моем файле JavaScript:

    window.addEventListener("load", function() {

      var highlightButton = document.getElementById("highlight");
      highlightButton.addEventListener('click', search);

      function search(node) {
       if (node.nodeType === 1) {
       var spanEl = document.createElement("span");
       spanEl.className = "hoverNode";
       node.appendChild(spanEl);
       spanEl.innerHTML = spanEl.parentNode.tagName;
     }
   }
 })

Я понимаю, как добавить дочерний узел, но я не знаю, как пройти весь DOM и добавить дочерний узел к каждый элемент.

Ответы [ 2 ]

2 голосов
/ 10 февраля 2020

Учитывая, что «каждый элемент тела» фактически означает «каждый элемент в теле», вы можете начать с элемента и получить все его дочерние элементы. L oop над дочерними элементами и, если любой имеет тип 1 и имеет дочерние узлы, вы снова вызываете функцию с элементом.

Если у него нет дочерних элементов, go для следующего дочернего элемента и др. c. Следующее является просто примером повторения по всем узлам и выбора только типа 1. Вы можете изменить его, чтобы сделать что угодно.

// Call with a document or HTML element
function checkBodyElements(node) {

  // Recursive function
  function traverseBody(node) {

    if (node.childNodes.length) {

      // Loop over every child node
      node.childNodes.forEach(child => {

        // If it's a type 1, call the function recursively
        if (child.nodeType == 1) {
          console.log(child.tagName, child.nodeType)
          traverseBody(child);
        }
      });
    }
  }

  // Get the body element      
  let body = node.querySelector('body');
  
  // If a body element was found, traverse its children
  if (body) {
    traverseBody(body);
  }
}

window.onload = checkBodyElements(document);
<div>
  <div>
    <p><span></span>
    </p>
  </div>
  <div>
    <p><span></span>
    </p>
  </div>

</div>
0 голосов
/ 10 февраля 2020

Существует ли какая-либо конкретная c причина, которая подразумевает создание рекурсивной функции , кроме поддержки более старых браузеров, таких как IE6 и 7?

Если нет , вы можете просто использовать document.body.querySelectorAll('*') для выбора каждого узла элемента в DOM, игнорируя те, которые находятся вне элемента body. Примером может быть:

window.addEventListener('load', function () {
    var highlightButton = document.getElementById("highlight");

    function search () {
        document.body.querySelectorAll('*').forEach(function (el) { 
            var spanEl = document.createElement('span');

            spanEl.innerHTML = el.tagName; 
            spanEl.className = 'hoverNode';
            el.appendChild(spanEl); 
        });
    }

    highlightButton.addEventListener('click', search);
});

Если да , то вариант будет:

window.addEventListener('load', function () {
    var highlightButton = document.getElementById("highlight");

    // traverse downwards from rootEl while excluding Comment elements on IE6 7 & 8
    function traverseDOMFrom (rootEl, iterator) {
        if (!rootEl || rootEl.nodeType !== 1 || typeof iterator !== 'function') {
            return;
        }

        if (rootEl.children && rootEl.children.length > 0) {
            Array.prototype.slice.call(rootEl.children).forEach(function (el) {
                traverseDOMFrom(el, iterator);
            });
        }

        iterator(rootEl);
    }

    function search () {
        traverseDOMFrom(document.body, function (el) { 
            var spanEl = document.createElement('span');

            spanEl.innerHTML = el.tagName;
            spanEl.className = 'hoverNode';
            el.appendChild(spanEl); 
        });
    }

    highlightButton.addEventListener('click', search);
});

Обратите внимание, что в обоих случаях полифил для Array.prototype.forEach() и для EventTarget.addEventListener() понадобятся, если вы хотите поддерживать эти функции в IE6, 7 и 8! В противном случае вы также можете достичь тех же результатов, перебирая вместо этого массив элемента с пользовательским для l oop, так как для этого .addEventListener можно использовать простой обработчик события .onload , если нет необходимости поддерживать несколько прослушивателей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...