只有Internet Explorer似乎具有元素属性:canHaveHtml(MSDN,Dottoro).除了使用带有标记名列表的正则表达式之外,我似乎无法在其他浏览器中找到任何模拟它的东西.有没有办法在Chrome,Firefox等中确定这一点?
例如,有没有办法检查innerHTML房产,这100%相当吗?
我相信没有关于这一点的规范:
\n\nhttp://www.w3.org/TR/domcore/#concept-node-append
\n\n例如,在 Firefox、Chrome 和 Safari 中,您实际上可以向元素添加节点,<input>例如:
var input = document.createElement("input");\nvar div = document.createElement("div");\n\ndiv.textContent = \'hello\';\n\nconsole.log(input.outerHTML, input.childNodes.length);\n\ninput.appendChild(div);\n\nconsole.log(input.outerHTML, input.childNodes.length);\nRun Code Online (Sandbox Code Playgroud)\n\n它们只是没有被渲染。但在这两种情况下它们都被视为input节点的子节点。如果是 Firefox,则outerHTML不会更改,仅childNodes长度报告 1,如果是 Chrome 和 Safari ,则从outerHTML更改为<input>。<input></input>\n在 Firefox 中,与 Safari 和 Chrome 相反,innerHTML实际上返回子级的 HTML,即使它\未渲染且未返回outerHTML.
更新:\n正如 @Bergi 在 @M\xc3\xa5rtenWikstr\xc3\xb6m 答案中指出的那样,像我之前所做的方法对于可以包含内容(例如textarea,甚至 )title但不是 HTML 内容的元素来说并不能很好地工作。因此,更好的canHaveHTML可能是这样的:
// Improving the `canHaveHTML` using `canHaveChildren`,\n// using the approach shown by M\xc3\xa5rten Wikstr\xc3\xb6m\nfunction canHaveChildren(node) {\n // Uses the native implementation, if any.\n // I can\'t test on IE, so maybe it could be worthy to never use\n // the native implementation to have a consistent and controlled\n // behaviors across browsers. In case, just remove those two lines\n if (node && node.canHaveChildren)\n return node.canHaveChildren();\n\n // Returns false if it\'s not an element type node; or if it has a end tag.\n // Use the `ownerDocument` of the `node` given in order to create\n // the node in the same document NS / type, rather than the current one,\n // useful if we works across different windows / documents.\n return node.nodeType === 1 && node.ownerDocument\n .createElement(node.tagName).outerHTML.indexOf("></") > 0;\n}\n\nfunction canHaveHTML(node) {\n // See comment in `canHaveChildren` about native impl.\n if (node && node.canHaveHTML)\n return node.canHaveHTML();\n\n // We don\'t bother to create a new node in memory if it\n // can\'t have children at all\n if (!canHaveChildren(node))\n return false;\n\n // Can have children, then we\'ll check if it can have\n // HTML children.\n node = node.ownerDocument.createElement(node.tagName);\n\n node.innerHTML = "<b></b>";\n\n // if `node` can have HTML children, then the `nodeType`\n // of the node just inserted with `innerHTML` has to be `1`\n // (otherwise will be likely `3`, a textnode).\n return node.firstChild.nodeType === 1; \n}\nRun Code Online (Sandbox Code Playgroud)\n\n在 Firefox、Chrome 和 Safari 中测试;应该覆盖所有节点和所有场景。
\n您可以使用以下函数来确定命名元素是否可以有子元素。
然而,正如 ZER0 所指出的,这可能更像是 IE 的canHaveChildren而不是canHaveHtml的替代品,因为它对于“应该”不为空的任何标签名称返回 true。
function canHaveHtml(tag) {
return document.createElement(tag).outerHTML.indexOf("></") > 0;
}
Run Code Online (Sandbox Code Playgroud)
它利用了这样一个事实:新创建的元素不能(或不应该)有内容,没有outerHtml结束标签。
例如:
document.createElement("input").outerHTML === "<input>"
Run Code Online (Sandbox Code Playgroud)
和
document.createElement("div").outerHTML === "<div></div>"
Run Code Online (Sandbox Code Playgroud)
除了使用带有标记名列表的正则表达式之外,我似乎无法在其他浏览器中找到任何东西来模拟它。
它可能看起来不优雅或不聪明,但创建白名单(或黑名单)是最简单、最快、最可靠的方法。你不需要正则表达式;您可以使用简单的结构(例如关联数组)来创建。
// blacklist approach
var noChildren = {
input: true,
meta: true,
br: true,
link: true,
img: true
// other properties here
};
function canHaveChildren(tagName) {
tagName = tagName.toLowerCase();
alert(noChildren[tagName] === undefined);
}
canHaveChildren("BR");
canHaveChildren("div");
Run Code Online (Sandbox Code Playgroud)
演示: http: //jsfiddle.net/FTbWa/
可重用功能:Github Gist
这种范式并非没有先例。它被用在许多脚本库和 HTML 解析器/清理器中。例如,查看 jQuery 的源代码,您会注意到许多特定于元素的测试以及元素名称和属性名称的数组。
| 归档时间: |
|
| 查看次数: |
1613 次 |
| 最近记录: |