4

(在第一个问题非常制定之后,我再次问我的问题)

我面临以下问题:

<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吗?

4

6 回答 6

3

colorSelector被注释掉了。JavaScript 仅在 DOM 中有效,注释掉的部分不在 DOM 中。

于 2011-09-30T16:59:34.557 回答
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确实有效。

于 2011-09-30T17:16:01.480 回答
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 友好的。

于 2011-09-30T20:10:43.360 回答
0

我现在附加第一个 div

你是怎样做的?您拥有的responseXML是 XML 元素,而不是 HTML 元素。

  • 您不应该将appendChild它们转换成非 XHTML HTML 文档;

  • 实际上,您根本不应该将appendChild它们放入另一个文档中,您应该使用importNode将元素从一个文档获取到另一个文档,否则您应该得到WRONG_DOCUMENT_ERR;

  • 即使您由于浏览器的松懈而设法将它们插入到 HTML 中,它们仍然是 XML 元素,而不是语义上的 HTML 元素。class因此,这些属性没有什么特别之处;仅具有该名称并不会使该属性实际上代表一个类。getElementsByClassName不会仅仅因为元素具有name class的属性而返回元素;它们必须是元素,其语言定义将属性与类的概念(通常意味着 HTML、XHTML 或 SVG)相关联。

(属性也应该如此id;仅调用一个属性id并不能使其在概念上成为ID. 所以getElementById不应该工作。有一种方法可以将任意 XML 属性与 ID-ness 相关联,但您没有得到具有类性,通过<!ATTLIST在文档类型中使用声明。但通常不值得打扰。xml:id在支持 XML ID 的实现中也是一种特殊情况。)

如果您使用的是原生 XHTML 页面,则可以通过xmlns在内容上放置合适的属性使其成为实际 XHTML 而不仅仅是任意 XML,然后使用importNode. 但总的来说这是不值得的。返回 HTML 标记字符串(通常为 JSON)或原始 XML 数据往往更简单,客户端脚本可以从中构造 HTML 元素本身。

于 2011-09-30T19:59:30.400 回答
0
<!--<div class="colorSelector" id="0-0">
        <div class="gbSelector" id="1-0">
            <table style="none" id="2-0"></table>
        </div>
    </div>-->

上面的代码是灰色的,原因是:它是一个注释。评论根本不被浏览器解析,对页面没有任何影响。

您必须解析 HTML,阅读评论,并使用评论的内容创建一个的DOM 对象。

于 2011-09-30T17:00:22.140 回答
0

请描述您对返回结果的操作。nodeList 和 node 之间存在显着差异, nodeLists 是LIVE

因此,如果您将由getElementsByClassName()(或类似)返回的 nodeList 分配给变量,则当您从 DOM 中删除 nodeList 内的节点时,此变量将更改。

于 2011-09-30T17:57:02.683 回答