【问题标题】:Javascript Replace Child/Loop issueJavascript替换子/循环问题
【发布时间】:2012-11-04 16:37:18
【问题描述】:

我有一个非常奇怪的问题,我有一个 forloop,它应该将所有具有“原始”类的 div 替换为具有“新”类的文本输入。当我运行循环时,它只用输入替换所有其他 div,但如果我运行循环只是替换 div 的类而不将标签更改为输入,它会执行每个 div,并且不仅互相做​​。

这是我的循环代码,以及实时版本的链接:live version here

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]);
        }
    }
}

【问题讨论】:

  • 反向迭代而不是正向迭代。当您删除 div 时,它也会从 divs 集合中删除,因此您最终会跳过索引。
  • 啊,所以有 var i = divs.length; i>0;我——?
  • 是的,差不多。 var i = divs.length - 1; i &gt; -1; i--
  • 啊,太棒了。太糟糕了,您没有将此作为答案发布。大声笑
  • @user1689607 或for ( var i = divs.length - 1; i--; )...

标签: javascript for-loop parent-child


【解决方案1】:

因为 divs 集合在其 div 元素之一从 DOM 中删除时会更新,因此您最终会跳过 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/

【讨论】:

    【解决方案3】:

    另一个解决方案是从一个类似数组的对象创建一个数组,然后对其进行迭代。例如:

    var divs = document.getElementsByTagName("div");
    
    Array.from(divs).forEach(function(el) {
      if (el.className == 'original') {
            var textInput = document.createElement('input');
            textInput.className = 'new';
            textInput.type = 'text';
            textInput.value = el.innerHTML;
            var parent = el.parentNode;
            parent.replaceChild(textInput, el);
        }
    });
    

    我最喜欢这个,因为它产生的代码最少,而且非常清晰!

    【讨论】:

      【解决方案4】:

      我不知道为什么,但是这个似乎最终起作用了:

      ModalBody.insertAdjacentHTML('afterbegin', loader.outerHTML);
      

      我的loader基本上只是一个新的div,但是在div里面有这个加载符号,在加载内容的时候出现。

      var loader = document.createElement('div');
      loader.classList.add('loader');
      loader.classList.add('is-loading');
      loader.classList.add('mt-5');
      

      所以只有这一行

      ModalBody.insertAdjacentHTML('afterbegin', loader);
      

      ...当内容被加载时,很快就会显示 [object HTMLDivElement],3 秒后或多或少会出现正确的内容。一旦我添加了这个“.outerHTML”,事情就变得正确了。我仍然是一个超级初学者。那么,也许有人也可以解释一下为什么会这样?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-08
        • 2020-09-15
        • 1970-01-01
        相关资源
        最近更新 更多