Mor*_*eng 21 javascript dom comments
这听起来有点疯狂,但我想知道是否有可能获得对comment元素的引用,以便我可以使用JavaScript动态替换其他内容.
<html>
<head>
</head>
<body>
<div id="header"></div>
<div id="content"></div>
<!-- sidebar place holder: some id-->
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
在上面的页面中,我可以参考注释块并将其替换为本地存储中的某些内容吗?
我知道我可以有一个div占位符.只是想知道它是否适用于评论块.谢谢.
hyp*_*lug 27
var findComments = function(el) {
var arr = [];
for(var i = 0; i < el.childNodes.length; i++) {
var node = el.childNodes[i];
if(node.nodeType === 8) {
arr.push(node);
} else {
arr.push.apply(arr, findComments(node));
}
}
return arr;
};
var commentNodes = findComments(document);
// whatever you were going to do with the comment...
console.log(commentNodes[0].nodeValue);
Run Code Online (Sandbox Code Playgroud)
min*_*.dk 12
关于使用注释作为占位符似乎存在合法(性能)问题 - 例如,没有可以匹配注释节点的CSS选择器,因此您将无法使用例如查询它们document.querySelectorAll(),这使得它既复杂又位置慢评论元素.
我的问题是,是否有另一个我可以放置内联的元素,它没有任何明显的副作用?我见过一些人使用<meta>标签,但我调查了这一点,并使用它<body>是无效的标记.
所以我决定使用<script>标签.
使用自定义type属性,因此它实际上不会作为脚本执行,并使用data-属性来初始化占位符的脚本所需的任何初始化数据.
例如:
<script type="placeholder/foo" data-stuff="whatevs"></script>
Run Code Online (Sandbox Code Playgroud)
然后只需查询这些标签 - 例如:
document.querySelectorAll('script[type="placeholder/foo"]')
Run Code Online (Sandbox Code Playgroud)
然后根据需要替换它们 - 这是一个简单的DOM示例.
请注意,placeholder在此示例中不是任何已定义的"真实"事物 - 您应该将其替换为例如vendor-name以确保您type不会与任何"真实"冲突.
建立Hyperslug的答案,你可以通过使用堆栈而不是函数递归来加快速度.如此jsPerf所示,Windows上的Chrome 36上的函数递归速度降低了42%,IE8兼容模式下的IE11的函数递归速度降低了71%.在边缘模式下IE11的运行速度似乎慢了约20%,但在所有其他测试情况下运行速度更快.
function getComments(context) {
var foundComments = [];
var elementPath = [context];
while (elementPath.length > 0) {
var el = elementPath.pop();
for (var i = 0; i < el.childNodes.length; i++) {
var node = el.childNodes[i];
if (node.nodeType === Node.COMMENT_NODE) {
foundComments.push(node);
} else {
elementPath.push(node);
}
}
}
return foundComments;
}
Run Code Online (Sandbox Code Playgroud)
或者像在TypeScript中一样:
public static getComments(context: any): Comment[] {
var foundComments = [];
var elementPath = [context];
while (elementPath.length > 0) {
var el = elementPath.pop();
for (var i = 0; i < el.childNodes.length; i++) {
var node = el.childNodes[i];
if (node.nodeType === Node.COMMENT_NODE) {
foundComments.push(node);
} else {
elementPath.push(node);
}
}
}
return foundComments;
}
Run Code Online (Sandbox Code Playgroud)
有一个用于文档节点遍历的 API Document#createNodeIterator():
var nodeIterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_COMMENT
);
// Replace all comment nodes with a div
while(nodeIterator.nextNode()){
var commentNode = nodeIterator.referenceNode;
var id = (commentNode.textContent.split(":")[1] || "").trim();
var div = document.createElement("div");
div.id = id;
commentNode.parentNode.replaceChild(div, commentNode);
}Run Code Online (Sandbox Code Playgroud)
#header,
#content,
#some_id{
margin: 1em 0;
padding: 0.2em;
border: 2px grey solid;
}
#header::after,
#content::after,
#some_id::after{
content: "DIV with ID=" attr(id);
}Run Code Online (Sandbox Code Playgroud)
<html>
<head>
</head>
<body>
<div id="header"></div>
<div id="content"></div>
<!-- sidebar placeholder: some_id -->
</body>
</html>Run Code Online (Sandbox Code Playgroud)
编辑:使用NodeIterator而不是TreeWalker