Передача элемента после изменения externalHTML

Я хочу изменить externalHTML какого-то элемента, а затем передать его функции, чтобы функция могла что-то с ним сделать:

const bars = document.getElementsByClassName('bar');

for (let i = bars.length - 1; i >= 0; i -= 1) {
  const bar = bars[i];
  bar.outerHTML = `<h1 class="bar">${bar.innerHTML}</h1>`;
  const foo = new Foo(bar);
  // ... some code
  foo.doFoo();
}

function Foo (bar) {
  this.bar = bar;
  this.doFoo = function() {
    this.bar.innerHTML = `Foo${this.bar.innerHTML}`;
    console.log('doFoo:', this.bar.innerHTML);
    // expected on page: "Dog" --> "FooDog", "Turtle" --> "FooTurtle". This doesn't happen.
  }
}
<p class="bar">Dog</p>
<p>Cat</p>
<p class="bar">Turtle</p>

Тем не менее, хотя DOM изменяется после изменения externalHTML, переменная bar все еще ссылается на "старую" (неизменную) версию элемента, которая, конечно, больше не существует в DOM. Поэтому невозможно изменить содержимое DOM.

Объяснение этого поведения на MDN:

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


Как я могу добиться, чтобы Foo-Object все еще знал правильный элемент в DOM, без необходимости повторного запроса DOM?

1 ответ

Одним из вариантов может быть получение ссылки на nextElementSibling элемент каждого из которых outerHTML ты собираешься измениться. Давайте назовем это next,

Затем, как только вы обновите outerHTML вы получаете обновленную ссылку на новый элемент с:

next.previousElementSibling

Или, на самом деле, если обновленный элемент уже является последним и nextElementSibling возвращенный undefined

next ? next.previousElementSibling : bar.parentElement.lastChild

const bars = document.getElementsByClassName('bar');

for (let i = bars.length - 1; i >= 0; i -= 1) {
  const bar = bars[i];
  const next = bar.nextElementSibling;
  
  bar.outerHTML = `<h1 class="bar">${bar.innerHTML}</h1>`;
  
  const foo = new Foo(next.previousElementSibling || next.parentElement.lastChild);
  
  // ...
  
  foo.doFoo();
}

function Foo (bar) {
  this.bar = bar;
  
  this.doFoo = function() {
    this.bar.innerHTML = `Foo${ this.bar.innerHTML }`;
    console.log('doFoo:', this.bar.innerHTML);
    // expected on page: "Dog" --> "FooDog", "Turtle" --> "FooTurtle". This doesn't happen.
  }
}
<p class="bar">Dog</p>
<p>Cat</p>
<p class="bar">Turtle</p>

Другие вопросы по тегам