JavaScript, как мне перебрать каждый текущий и будущий элемент в коллекции HTML?

Коллекция HTMLCollection в HTML DOM активна; он автоматически обновляется при изменении базового документа.

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

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

как бы я использовал живую коллекцию HTML и выполнял функцию для каждого элемента в ней, даже для новых добавленных?

если я смогу это сделать, это должно привести к тому, что скрипт никогда не завершится и перекрасит все новые элементы.

любая помощь приветствуется!


person laundmo    schedule 22.09.2018    source источник
comment
Это не так работает. Вы сохраняете коллекцию в глобальной переменной, и всякий раз, когда вы перебираете ее, она будет содержать текущие элементы DOM. Но ничто автоматически не выполняет цикл всякий раз, когда коллекция изменяется.   -  person Barmar    schedule 22.09.2018
comment
Это яркий пример XY-проблемы - реальной проблемы, которую вы хотите решить. решить — это что-то вроде изменения любых элементов, которые соответствуют критериям, даже если они будут добавлены позже, но вы спрашиваете, как перебирать HTMLCollection. Если вы сможете сосредоточиться на сути своей проблемы, вы сможете найти лучшие альтернативы. На первый взгляд, это похоже на MutationObserver. может подойти лучше.   -  person VLAZ    schedule 22.09.2018
comment
@vlaz ооо, это имеет смысл. и вы видели ответ, который предлагает наблюдателя за мутациями, и я надеюсь, что смогу понять, как это сделать. Спасибо.   -  person laundmo    schedule 23.09.2018


Ответы (1)


Я бы использовал MutationObserver для выполнения этой задачи. Он будет следить за изменениями в узле и, при необходимости, также будет следить за изменениями в поддереве (что, я думаю, здесь не требуется). По мере добавления узлов мы можем отправить узел в функцию, чтобы применить к нему некоторую функцию. В приведенном ниже примере мы просто случайным образом выбираем цвет и устанавливаем фон.

let targetNode = document.getElementById('watch')

// Apply feature on the node
function colorNode(node) {
  let r = Math.floor(Math.random() * 255)
  let g = Math.floor(Math.random() * 255)
  let b = Math.floor(Math.random() * 255)
  node.style.background = `rgb(${r},${g},${b})`
}

// Watch the node for changes (you can watch the subTree if needed)
let observerOptions = {
  childList: true
}

// Create the callback for when the mutation gets triggered
let observer = new MutationObserver(mutationList => {
  // Loop over the mutations
  mutationList.forEach(mutation => {
    // For added nodes apply the color function
    mutation.addedNodes.forEach(node => {
      colorNode(node)
    })
  })
})

// Start watching the target with the configuration
observer.observe(targetNode, observerOptions)

/////////////////
/// Testing
/////////////////
// Apply the inital color
Array.from(targetNode.children).forEach(child => colorNode(child))

// Create nodes on an interval for testing
setInterval(() => {
  let newNode = document.createElement('div')
  // Some random text
  newNode.textContent = (Math.random() * 1000).toString(32)
  targetNode.appendChild(newNode)
}, 2000)
<div id="watch">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

person Get Off My Lawn    schedule 22.09.2018