Повторное присоединение сглаживателя к кнопке - PullRequest
0 голосов
/ 13 ноября 2018

Этот вопрос относится к другому вопросу о SO .Я не перефразирую его, поэтому, пожалуйста, сначала прочтите это.

При решении вышеупомянутой проблемы я столкнулся с поведением, которое мне неизвестно.

Этот фрагмент работает:

var bt1;
document.addEventListener('DOMContentLoaded', load);

function load() {
  document.body.innerHTML += '<div>welcome</div>';
  bt1 = document.getElementById('bt1');
  bt1.onclick = clicked;
}

function clicked(a) {
  document.body.innerHTML += '<div>welcome</div>';
  // getting the button from document.getElement method
  bt1 = document.getElementById('bt1');
  bt1.onclick = clicked;
}
<body>
  <button id="bt1">Click Me</button>
</body>

Пока это не так:

var bt1;
document.addEventListener('DOMContentLoaded', load);

function load() {
  document.body.innerHTML += '<div>welcome</div>';

  bt1 = document.getElementById('bt1');
  bt1.onclick = clicked;
}

function clicked(a) {
  document.body.innerHTML += '<div>welcome</div>';
  // getting the button from event.target
  var b = a.target;
  b.onclick = clicked;
}
<body>
  <button id="bt1">Click Me</button>
</body>

Любое понимание поможет прояснить понятия.

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

Element.innerHTML заменяет все, что находится внутри данного элемента DOM.

Чтобы вставить HTML-код в документ, а не заменить содержимое элемента, используйте метод Element.insertAdjacentHTML () , который позволит вам работать с атрибутом target так, как вы хотите.

var bt1;
document.addEventListener('DOMContentLoaded', load);

function load() {
  document.body.innerHTML += '<div>welcome</div>';

  bt1 = document.getElementById('bt1');
  bt1.onclick = clicked;
}

function clicked(a) {
  console.log(a.srcElement);
  document.body.insertAdjacentHTML('beforeend', '<div>welcome</div>');
  // getting the button from event.target
  var b = a.target;
  b.onclick = clicked;
}
<body>
  <button id="bt1">Click Me</button>
</body>
0 голосов
/ 13 ноября 2018

Кнопка bt1 воссоздается в нажатой функции - и a.target указывает на старую кнопку, а не на новую.

Строка document.body.innerHTML += '<div>welcome</div>'; не просто добавляет div к телу, но устанавливает innerHTML полного тела, что вызывает повторную инициализацию всех элементов внутри тела. В первом примере кода вы извлекаете вновь созданную кнопку по идентификатору (потому что getElementById вызывается после присвоения innerHTML), но во втором примере ссылается на старую кнопку, которая больше не отображается в браузере.

Этот метод добавления материала к телу является запахом кода, потому что браузер должен воссоздать что-либо внутри тела. Лучшим решением было бы использовать appendChild API. При этом кнопка не создается заново, и вам не нужно повторно подключать прослушиватель событий:

var bt1;
document.addEventListener('DOMContentLoaded', load);

function load() {
  document.body.innerHTML += '<div>welcome</div>';
  bt1 = document.getElementById('bt1');
  bt1.onclick = clicked;
}

function clicked(a) {
  var newDiv = document.createElement('div');
  newDiv.textContent = 'welcome';
  document.body.appendChild(newDiv);
}
...