Javascript 对后来通过 Javascript 添加的元素执行失败

Javascript execution failed on elements which were added later through Javascript

在我目前正在做的一个项目中,有很多项目需要打开一个对话框。对于每个新对话框,内部数据都会发生变化,而且我已经使用 Javascript 完成了更改。现在,如果我在 Javascript 的对话框中添加任何元素(例如复选框),material js 将无法正常工作。所以我检查了一个类似的问题并得到了答案,我已经实施但仍然不起作用。 在这个片段中,我做了一个类似的情况。添加按钮用于添加到对话框,当对话框打开时,复选框的行为与页面加载期间对话框中的行为不同。为了表明这一点,我在它本身之前添加了一个复选框,而不是来自 Javascript。从 Javascript 添加复选框后,旧的现有复选框也不起作用。

请帮助我,这将有很大的帮助。

function resetJs(path) {
  var scripts = document.getElementsByTagName('script'),
    newScript = document.createElement("script");

  newScript.src = path + "?timestamp=" + Math.round(new Date().getTime() / 1000);

  for (var i = 0; i < scripts.length; ++i) {
    var srcUrl = scripts[i].getAttribute('src');
    if (srcUrl && srcUrl.indexOf(path) > -1) {
      scripts[i].parentNode.replaceChild(newScript, scripts[i]);
    }
  }
}
var dialog = document.querySelector('dialog');

var addData = document.querySelector('#add');
addData.addEventListener('click', function() {
  var data = document.querySelector('#dialogContent');
  data.innerHTML += '<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-1"><input type="checkbox" id="checkbox-1" class="mdl-checkbox__input" checked><span class="mdl-checkbox__label">Checkbox From JS</span></label>';

});



var showDialogButton = document.querySelector('#show-dialog');
if (!dialog.showModal) {
  dialogPolyfill.registerDialog(dialog);
}
showDialogButton.addEventListener('click', function() {

  dialog.showModal();
  resetJs('https://code.getmdl.io/1.3.0/material.min.js');
});
dialog.querySelector('.close').addEventListener('click', function() {
  dialog.close();
});
<link href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css" rel="stylesheet"/>
<script src="https://code.getmdl.io/1.3.0/material.min.js"></script>
<button id="show-dialog" type="button" class="mdl-button">Show Dialog</button>
<button id="add" type="button" class="mdl-button">Add</button>
<dialog class="mdl-dialog">
  <h4 class="mdl-dialog__title">Allow data collection?</h4>
  <div class="mdl-dialog__content" id="dialogContent">
    <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-1"><input type="checkbox" id="checkbox-1" class="mdl-checkbox__input" checked><span class="mdl-checkbox__label">Checkbox Added Before</span></label>
    <p>
      Allowing us to collect data will let us get you the information you want faster.
    </p>
  </div>
  <div class="mdl-dialog__actions">
    <button type="button" class="mdl-button">Agree</button>
    <button type="button" class="mdl-button close">Disagree</button>
  </div>
</dialog>

来自 mdl here

的文档

Material Design Lite will automatically register and render all elements marked with MDL classes upon page load. However in the case where you are creating DOM elements dynamically you need to register new elements using the upgradeElement function.

因此,您可以在 addData 函数中执行操作;

var addData = document.querySelector("#add");
  addData.addEventListener("click", function() {
    var data = document.querySelector("#dialogContent");
    var label = document.createElement("label");
    label.className = "mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect";
    label.innerHTML =
      '<input type="checkbox" id="checkbox-1" class="mdl-checkbox__input" checked><span class="mdl-checkbox__label">Checkbox From JS</span>';
    label.htmlFor = "checkbox-1";
    componentHandler.upgradeElement(label);
    data.appendChild(label);
  });

您需要使用 componentHandler.upgradeElement 将动态创建的元素升级为 material 元素,然后将子元素附加到数据。

请看这个codesandbox