getElementsByClassName关闭问题

时间:2014-12-01 05:50:58

标签: javascript dom closures

似乎getElementsByClassName每次都从关闭之外重新执行。

我可以通过将元素复制到数组中来解决这个问题,但我不知道是否有更好的方法。

这是一个代码示例:

HTML

<body>
    <ul>
        <li class="tab">Parent Tab 1</li>
        <li class="tab">Parent Tab 2</li>
    </ul>
    <div class="tab-content">Parent Content 1</div>
    <div class="tab-content">Parent Content 2</div>

    <!-- dynamically generated by javascript -->
    <div id="unrelatedContent">
        <ul>
            <li class="tab">Child Tab 1</li>
            <li class="tab">Child Tab 2</li>
        </ul>
        <div class="tab-content">Child Content 1</div>
        <div class="tab-content">Child Content 2</div>
    </div>
</body>

的JavaScript

var tabs = function(parent) {
    var tabs = parent.getElementsByClassName("tab");
    var tabContents = parent.getElementsByClassName("tab-content");
    var tabContentsById = {};
    var t1 = [];
    var t2 = [];

    //copy to an array. it seems like chrome re-evaluates
    //the getElementsByClassName part on click, meaning you cant
    //have nested tabs otherwise the parent will affect the children
    //(because itll match the childrens tab and tab-content)
    /*
    for (var i = 0; i < tabs.length; i++) {
        t1.push(tabs[i]);
    }
    for (var i = 0; i < tabContents.length; i++) {
        t2.push(tabContents[i]);
    }
    tabs = t1;
    tabContents = t2;
    */

    for (var i = 0; i < tabs.length; i++) {
        var tab = tabs[i];
        tab.onclick = function() {
            console.log(tabs);
        }
    }
}

tabs(document.getElementsByTagName("body")[0]);

parentTab1.click(); //length = 2

//pretend like unrelatedContent was dynamically generated via dom methods
document.getElementsByTagName("body")[0].appendChild(unrelatedContent);
tabs(unrelatedContent);

parentTab1.click(); //length = 4

1 个答案:

答案 0 :(得分:2)

document.getElementsByClassName()的结果是HTMLCollection,它是元素的实时集合。如果您不希望在向文档添加更多元素时更新此集合,则需要复制到数组中;这是克隆容器的简单方法:

var tabs = [].slice.call(parent.getElementsByClassName("tab"), 0);
var tabContents = [].slice.call(parent.getElementsByClassName("tab-content"), 0);

另请参阅:Array.prototype.slice