Передача элемента после изменения externalHTML - PullRequest
0 голосов
/ 10 мая 2018

Я хочу изменить 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 Ответ

0 голосов
/ 10 мая 2018

Одним из вариантов может быть получение ссылки на элемент 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>
...