网站搜索

Javascript 替换子元素/循环问题


我遇到了一个非常奇怪的问题,我有一个 for 循环,它本应该将所有类为“original”的 div 替换为类为“new”的文本输入框。当我运行这个循环时,它只替换每隔一个的 div 为输入框,但如果我运行循环只是替换 div 的类而不改变标签为输入框,它会替换每一个 div,而不是只替换每隔一个。

这是我的循环代码,以及一个实时版本的链接:实时版本在这里

function divChange()    {
    var divs = document.getElementsByTagName("div");
    for (var i=0; i<divs.length; i++) {
        if (divs[i].className == 'original') {
            var textInput = document.createElement('input');
            textInput.className = 'new';
            textInput.type = 'text';
            textInput.value = divs[i].innerHTML;
            var parent = divs[i].parentNode;
            parent.replaceChild(textInput, divs[i]);
        }
    }
}

答案#1

因为当 DOM 中的一个 div 元素被移除时,divs 集合会被更新,所以你会跳过一些 div,因为在集合重新索引时,你的 i 没有更新。

一个常见的解决方案是改为反向迭代。

function divChange()    {
    var divs = document.getElementsByTagName("div");
    for (var i=divs.length - 1; i > -1; i--) {
        if (divs[i].className == 'original') {
            var textInput = document.createElement('input');
            textInput.className = 'new';
            textInput.type = 'text';
            textInput.value = divs[i].innerHTML;
            divs[i].parentNode.replaceChild(textInput, divs[i]);
        }
    }
}

答案#2

你可以使用的另一种解决方案是将实时 HTMLCollection 复制到一个非活动数组中,然后使用你原来的逻辑:

function divChange() {
    var divs = document.getElementsByTagName("div");
    divs = Array.prototype.slice.call( divs ); //convert to array
    for (var i = 0; i < divs.length; i++) {
        if (divs[i].className == 'original') {
            var textInput = document.createElement('input');
            textInput.className = 'new';
            textInput.type = 'text';
            textInput.value = divs[i].innerHTML;
            var parent = divs[i].parentNode;
            parent.replaceChild(textInput, divs[i]);
        }
    }
}

divChange();

http://jsfiddle.net/2UCZa/1/