Javascript GetElementsByCassName返回[],而不是异步附加节点

Javascript GetElementsByCassName返回[],而不是异步附加节点,javascript,ajax,getelementsbyclassname,Javascript,Ajax,Getelementsbyclassname,(在第一个问题制定得很糟糕之后,我再次提出了我的问题) 我面临以下问题: <div class="testA" id="test1"></div> 进入预定义的div <div class="testA" id="test1"> 最终文档如下所示(使用开发工具检查): 当我现在尝试使用getElementById(“0-0”)获取元素时,我得到了预期的结果 但是使用getElementsByClassName(“颜色选择器”)返回[] 我错过什么了

(在第一个问题制定得很糟糕之后,我再次提出了我的问题)

我面临以下问题:

<div class="testA" id="test1"></div>
进入预定义的
div

<div class="testA" id="test1">

最终文档如下所示(使用开发工具检查):


当我现在尝试使用
getElementById(“0-0”)
获取元素
时,我得到了预期的结果

但是使用
getElementsByClassName(“颜色选择器”)
返回
[]


我错过什么了吗?这可能是节点类型为
元素而不是
HTMLElement
这一事实的遗留问题吗?

颜色选择器
被注释掉。JavaScript只在DOM中工作,注释掉的部分不在DOM中。


<!--<div class="colorSelector" id="0-0">
        <div class="gbSelector" id="1-0">
            <table style="none" id="2-0"></table>
        </div>
    </div>-->
上面的代码是灰色的,原因是:它是一个注释。浏览器根本不会解析注释,对页面没有任何影响


您必须解析HTML,读取注释,并使用注释内容创建一个新的DOM对象。

既然您说您的
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
确实有效。

请描述您对返回结果所做的操作。节点列表和节点之间存在显著差异,节点列表是活的

因此,如果将
getElementsByClassName()
(或类似)返回的节点列表分配给变量,则当从DOM中删除节点列表中的节点时,该变量将发生更改

我现在附加第一个div

你是怎么做到的?
responseXML
中包含的是XML元素,而不是HTML元素

  • 您不应该
    appendChild
    将它们添加到非XHTML文档中

  • 实际上,您根本不应该
    appendChild
    将它们添加到另一个文档中,您应该使用
    importNode
    将元素从一个文档添加到另一个文档中,否则您应该会得到
    错误的文档

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

(对于
id
属性也是如此;仅仅拥有一个名为
id
的属性并不能使它在概念上成为
id
。因此
getElementById
不应该起作用。通过在t中使用
声明,可以将任意XML属性与id ness关联起来,这是类ness无法实现的不过,doctype通常不值得费心。而且
xml:id
是一个特例,在支持xml-id的实现中。)


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

以下是一种针对Firefox、Opera、Chrome和Safari的方法。基本上,您只需执行div.innerHTML=div.innerHTML即可将其内容重新解释为HTML,这将使XML文件中的class属性被视为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>

就空元素的结束标记而言,只要标记是HTML友好的。

节点是否真的被注释掉了?如果不是,调用
getElementsByClassName
的上下文是什么?真正的问题是,
GetElementById
为什么会得到注释掉的内容?你确定是吗返回内容?@thattmatthew:OP已验证
.getElementsByClassName
返回
[]
,这可能意味着控制台正在用于验证。我猜要么代码注释不存在,要么页面上有另一个元素具有相同的ID。是的,这也是我的两个猜测。是否有任何理由将此主题标记为XML?我想您需要提供一个演示,目前只有两个选项:这两种方法都返回结果或不返回结果。“使用getElementById(“0-0”)我得到了预期的结果。”注释节点在DOM中是最确定的。但是,它们被视为CDATA。在我看来不是很有注释性。“使用getElementById(“0-0”)我得到了预期的结果。”我有一个类似这样的函数:handleTmpl=function(tmplNode){element=parentEl.appendChild($t(“div”,0,tmplNode));var bgpolxels=element.getElementsByClassName(“gbSelector”)[0];}其中,tmplNode是通过立即处理响应元素接收的节点。getElementsByClassName(“gbSelector”)[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>
<!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>
var doc = this.responseXML;
var markup = (new XMLSerializer()).serializeToString(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0]);
div.innerHTML = markup;