(在第一个问题非常明确之后,我再次提出我的问题)
我遇到以下问题:
<div class="testA" id="test1"></div>
上面写的元素是预定义的。我现在通过XMLHttpRequest & Co.加载一个xml树,提供以下响应:
<response>
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</response>
我现在使用
附加第一个div
request.responseXML.getElementsByTagName("response")[0]
.getElementsByTagName("div")[0]
进入预定义的div
<div class="testA" id="test1">
最终文档如下所示(使用开发工具检查):
<div class="testA" id="test1">
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</div>
当我现在尝试使用<div class="colorSelector" id="0-0">
获取元素getElementById("0-0")
时,我得到了预期的结果。
但使用getElementsByClassName("colorSelector")
会返回[]
。
我错过了什么吗?它可能是节点属于Element
而不是HTMLElement
的事实的剩余部分吗?
答案 0 :(得分:3)
colorSelector
已被注释掉。 JavaScript只能在DOM中运行,注释掉的部分不在DOM中。
答案 1 :(得分:1)
既然你说你的getElementById("0-0")
成功了,那么显然你实际上没有注释掉节点。
我猜你在做:
document.getElementById("0-0").getElementsByClassName('colorSelector');
...这将无效,因为ID选择的元素没有该类的后代。
由于您在标记中显示HTML注释,我还想知道您是否在ID为"0-0"
的页面上有一些不同的元素。看一看。
如果您的节点实际已被注释掉,则需要先选择注释,并将其替换为内部包含的标记:
var container = document.getElementById('test1'),
comment = container.firstChild;
while( comment && comment.nodeType !== 8 ) {
comment = comment.nextSibling;
}
if( comment ) {
container.innerHTML = comment.nodeValue;
}
...导致:
<div class="testA" id="test1">
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</div>
...但是又一次,由于你的getElementsById
确实有效,这似乎不太可能。
答案 2 :(得分:0)
<!--<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>-->
上面的代码是灰色的,原因是:这是一个评论。浏览器根本不解析注释,对页面没有任何影响。
您必须解析HTML,阅读评论,并使用评论内容制作新 DOM对象。
答案 3 :(得分:0)
请描述您对返回的结果所做的工作。 nodeList和节点之间存在显着差异,nodeLists LIVE 。
因此,如果将getElementsByClassName()
(或类似)返回的nodeList分配给变量,则当您从DOM中删除nodeList中的节点时,此变量将会更改。
答案 4 :(得分:0)
我现在追加第一个div
你是怎么做到的?您在responseXML
中拥有的是XML元素,而不是HTML元素。
您不应该appendChild
将它们转换为非XHTML HTML文档;
实际上你根本不应该appendChild
将它们放到另一个文档中,你应该使用importNode
从一个文档到另一个文档中获取元素,否则你应该得到WRONG_DOCUMENT_ERR
;
即使您因浏览器松弛而设法将它们插入到HTML中,它们仍然是XML元素,而不是语义上的HTML元素。因此,class
属性没有什么特别之处;只是拥有该名称并不会使该属性实际上代表一个类。 getElementsByClassName
不会仅仅因为它们具有名称 class
的属性而返回元素;它们必须是其语言定义将属性与类的概念相关联的元素(通常意味着HTML,XHTML或SVG)。
(对于id
属性也应该如此;仅仅拥有一个名为id
的属性并不会使其在概念上成为ID
。所以getElementById
不应该通过在doctype中使用<!ATTLIST
声明,有一种方法可以将任意XML属性与ID-ness相关联,而这些属性并不是通过类别来实现的。虽然通常不值得打扰。另外{ {1}}是一种特殊情况,在支持XML ID的实现中。)
如果你使用native-XHTML页面,你可以通过在内容上放置合适的xml:id
属性来使其成为实际的XHTML而不仅仅是任意的XML,然后使用{{1} }。但总的来说这不值得;返回HTML标记字符串(通常是JSON)或客户端脚本可以从中构建HTML元素的原始XML数据往往更简单。
答案 5 :(得分:0)
这是Firefox,Opera,Chrome和Safari的一种方法。基本上,你只需要使用div.innerHTML = div.innerHTML将其内容重新解释为HTML,这将使XML文件中的类属性被视为HTML类名。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<script>
window.addEventListener("DOMContentLoaded", function() {
var div = document.getElementsByTagName("div")[0];
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var doc = this.responseXML;
div.appendChild(document.importNode(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0], true));
div.innerHTML = div.innerHTML;
alert(document.getElementsByClassName("colorSelector").length);
}
};
req.open("GET", "div.xml");
req.send();
}, false);
</script>
</head>
<body>
<div class="testA"></div>
</body>
</html>
如果您在本地支持xhr的浏览器中进行本地测试,请删除this.status === 200。
importNode()函数似乎在IE中不起作用(例如9)。我得到一个模糊的“界面不支持”错误。
你也可以这样做:
var doc = this.responseXML;
var markup = (new XMLSerializer()).serializeToString(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0]);
div.innerHTML = markup;
只要标记是HTML友好的,就空元素的结束标记而言。