JS: innerHTML и DOM не сотрудничают - PullRequest
2 голосов
/ 26 октября 2010

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

Это разбивается следующим образом:

  • Я добавил div и button, используя Javascript `appendChild '.
  • Я добавляю onclick обработчик для кнопки, работает отлично
  • Я добавляю-присваиваю innerHTML из div, чтобы добавить еще немного контента
  • Кнопка onclick вообще перестает работать

Вот пример сценария:

var D = document.createElement("DIV"), B = document.createElement("BUTTON");
B.innerHTML = "Is it true?";
document.body.appendChild(D);
D.appendChild(B);

B.onclick = function() { alert("Elvis Lives!"); }

На данный момент он работает нормально.Затем добавьте эту строку: ...

D.innerHTML += "What about Tupac?"; 

... и кнопка сломается.Итак, я просто сейчас использую appendChild для всех элементов.

Но -

  • Почему это происходит («похоже, это должно работать :)»)
  • Есть ли исправление (помимо добавления всех моих дополнительных элементов)?

Ответы [ 3 ]

4 голосов
/ 26 октября 2010

(это много образованных догадок) Я думаю, что когда вы изменяете D s innerHTML, дом в D разрушается и создается из нового значения.Поэтому, когда создается новое содержимое, вы получаете совершенно новый button, который отличается от B.поскольку вы устанавливаете обработчик onclick с помощью js, а не с помощью атрибута исходного элемента, новый button не имеет этой ссылки на функцию.однако B все еще работает, что можно продемонстрировать, позвонив по номеру

B.click();

после добавления к innerHTML.

, чтобы предотвратить избиение dom в пределах D, вы можете сделатьэто вместо использования innerHTML:

D.appendChild(document.createTextNode("What about Tupac?"));
3 голосов
/ 26 октября 2010

innerHTML - это ярлык для создания элементов DOM.Когда вы добавляете что-то к внешнему элементу div с помощью innerHTML, происходит следующее:

D.innerHTML += "What about Tupac?";

, что совпадает с

D.innerHTML = D.innerHTML + "What about Tupac?";

, что равно*

D.innerHTML = "<button>Is it true?</button>" + "What about Tupac?";

, который в итоге становится этим,

D.innerHTML = "<button>Is it true?</button>What about Tupac?";

Теперь на последнем шаге мы полностью заменили существующее содержимое div новой строкой, содержащей HTML.Что касается DOM, то не имеет значения, напечатал ли пользователь HTML вручную или он вызвал innerHTML на узле DOM.Все, что его волнует, это то, что он имеет строку HTML, которая должна быть преобразована в DOM.В это время создается новый элемент кнопки, поэтому onclick перестает работать - это уже не тот элемент.

1 голос
/ 26 октября 2010

Не ответ, просто тестовая страница - выглядит очень странно - я могу подтвердить ваши выводы

<script>
window.onload=function() {
  var D = document.createElement("DIV"), B = document.createElement("BUTTON");
  D.id = "div1"
  B.innerHTML = "Is it true?";
  B.onclick = function() { alert("Elvis Lives!"); }
  D.appendChild(B);
  document.body.appendChild(D);
}
</script>
<a href="" onclick="document.getElementById('div1').innerHTML += 'What about Tupac?'; return false">Click</a><br>
<a href="" onclick="alert(document.getElementsByTagName('button')[0].onclick); return false">Test</a>

обновление: извлеченные уроки - быть последовательными.

Это работает какожидается

<script>
window.onload=function() {
  var D = document.createElement("DIV");
  D.id = "div1"
  D.innerHTML = '<button onclick="alert(\'Elvis Lives!\')">Elvis</button>'
  document.body.appendChild(D);
}
</script>
<a href="" onclick="document.getElementById('div1').innerHTML += 'What about Tupac?'; return false">Click</a><br>
...