【发布时间】:2018-03-09 19:29:07
【问题描述】:
当具有标准 HTML 验证约束的表单字段(在本例中为 pattern 和 required)通过 .innerHTML 属性插入 DOM 时,该字段不会验证。我知道使用 .innerHTML 和 document.createElement() 创建元素在事件注册方面的区别,但之前没有遇到过这种副作用。
在我的特殊情况下,必须将大量 HTML 插入 DOM 并通过 document.createElement() 创建所有 HTML,然后设置所有节点属性并使用 .appendChild() 建立适当的层次结构是不可取的。
为什么会这样,如果可能的话,如何克服(请没有 jQuery 答案)?
注意:我知道 HTML <template>,但由于任何版本的 IE 都不支持它,所以它不适用于我。
在下面的 sn-p 中,第一个字段将正常工作,但第二个字段演示了我在说什么。如果您手动输入数据(在这种情况下为 5 位)或按下按钮以动态插入有效数据,则不会验证。
document.querySelector("div").innerHTML = `<input type="text" id="broken" name="zip" pattern="\d{5}" required placeholder="I don't.">`;
document.querySelector("input[type='button']").addEventListener("click", function(){
document.getElementById("broken").value = "12345"; // 12345 or "12345" - doesn't matter
});
:required { background:#f99; }
:valid { background:green; }
input[type=text] { width:250px; }
<input type="text" id="zip2" name="zip2" pattern="\d{5}" required placeholder="I work as I should (5 digits please).">
<div></div>
<input type="button" value="Populate">
【问题讨论】:
-
不要使用innerHTML 创建浏览器控件——它们不是文档元素,也不是纯HTML,它们是控件。控件可能会被创建并呈现在文档上,但有时无法初始化,或者至少它们的浏览器自动化可能不会触发。 innerHTML 非常适合纯 HTML 元素,对于其他任何东西,请使用 DOM。
-
@BekimBacaj 感谢您的意见(没有双关语),但您的描述并不完全正确。 HTML 世界中没有“控件”之类的东西。
.innerHTML实际上创建了 DOM 元素,它们是“纯”html。这些元素可以作为nodes 访问,并且可以正常交互。.innerHTML的唯一问题是事件注册和由于重新绘制和重新流动而导致的性能下降。 -
@BekimBacaj 当您使用
.innerHTML时,您只是要求用户代理解析HTML 内容的字符串,然后像往常一样处理该HTML。这与第一次加载页面时 UA 所做的没有什么不同,只是新解析的 HTML 必须“注入”到现有 DOM 中,因此也会出现时间问题(因此会出现事件注册问题)作为渲染问题。 -
@BekimBacaj 说了这么多,我同意使用 DOM API 创建和更新 DOM 通常是更好的方法,因为它更干净并且通常会产生更具可扩展性的代码。
-
@BekimBacaj 我鼓励您在聊天中查看我的 cmets。我已经这样做了很长时间,并且我非常确信您将操作系统和 UA 之间发生的事情与 UA 的 DOM Parser 和 JS 引擎中发生的事情混淆了。您对
.innerHTML的结果以及 DOM 的构建和更新方式也非常不正确。
标签: javascript html innerhtml html-validation