Когда изменяется внутренняя HTML, почему кажется, что элемент заменяется в консоли отладчика? - PullRequest
0 голосов
/ 09 февраля 2020

При использовании следующего кода внутри инструмента разработки Google Chrome он показывает, что root2 меняется каждую секунду, но root2 должно оставаться прежним. Если мы говорим, что меняется содержимое root2, то также обновляется и содержимое root1, но оно не мигает каждую секунду. Почему это так?

setInterval(function() {

  document.getElementById('root2').innerHTML = ("<h1>Hello, world!</h1><h2>" +
    new Date().toLocaleTimeString() + "</h2>");

}, 1000);
<div id="root1">
  <div id="root2"></div>
</div>

root2 мигает каждую секунду:

enter image description here

Ответы [ 2 ]

0 голосов
/ 15 февраля 2020

Поскольку они выделяют родительский узел любого узла, который был удален:

const sentence = 'click to remove last text node';
root2.append.apply(root2, [...sentence]);

onclick = e => {
  lastNode = root2.childNodes[ root2.childNodes.length - 1 ];
  if(lastNode) lastNode.remove();
};
<div id="root1">
  <div id="root2"></div>
</div>

Они также выделяют любой узел, который становится parentNode, так как они подсвечивают любой свернутый узел, в который добавляется новый узел:

(async function loop() {
  root2.append("first node insertion highlights the new parentNode");
  await wait(1000);
  // removal does too, as shown in previous snippet
  [...root2.childNodes].forEach(node => node.remove());
  await wait(1000);
  loop();
})();

function wait(ms) { return new Promise(res => setTimeout(res, ms)); }
<div id="root1">
  <div id="root2"></div>
</div>

Таким образом, когда вы изменяете, изменяете innerHTML вашего Элемента, происходят обе эти ситуации:

  • сначала все его содержимое удаляется => выделение,
  • , тогда ваш элемент становится parentNode (снова) => выделение.
0 голосов
/ 09 февраля 2020

Поскольку это так.

Использование присваивания innerHtml буквально отбрасывает «все в этом узле» и запускает новые дочерние узлы на основе использованной вами строки HTML. Эти новые узлы могут использовать точно такие же атрибуты, как и раньше, но они по-прежнему совершенно новые узлы.

Однако при использовании innerHTML вы меняете только узел дочерний контент . Не сам узел. Вот почему root1 ничего не меняет: ни один из его потомков не был удален / добавлен. Узел root2 действительно получил изменения своего дочернего содержимого, поэтому он сообщит, что что-то изменилось.

Если вы хотите сохранить узлы и просто обновить их, не используйте innerHTML. На самом деле, вообще не используйте innerHTML вообще, если только вы действительно не знаете, что делаете. Это почти никогда не решение какой-либо проблемы или вещи, которую вы пытаетесь решить / реализовать.

В этом конкретном c случае, когда кажется, что вы просто хотите обновить активную DOM на основе «вновь составленной строки, отражающей обновленное состояние DOM», взгляните на что-то вроде morphDOM .

...