Javascript Replace ChildLoop issue - Stack Overflow

I have this really bizarre issue where I have a forloop that is supposed to replace all divs with the c

I have this really bizarre issue where I have a forloop that is supposed to replace all divs with the class of "original" to text inputs with a class of "new". When I run the loop, it only replaces every-other div with an input, but if I run the loop to just replace the class of the div and not change the tag to input, it does every single div, and doesn't only do every-other.

Here is my loop code, and a link to the live version: 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]);
        }
    }
}

I have this really bizarre issue where I have a forloop that is supposed to replace all divs with the class of "original" to text inputs with a class of "new". When I run the loop, it only replaces every-other div with an input, but if I run the loop to just replace the class of the div and not change the tag to input, it does every single div, and doesn't only do every-other.

Here is my loop code, and a link to the live version: 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]);
        }
    }
}
Share Improve this question asked Nov 4, 2012 at 16:37 CJT3CJT3 2,9287 gold badges34 silver badges45 bronze badges 13
  • Iterate in reverse instead of forward. When you remove the div, it also gets removed from the divs collection, so you end up skipping indices. – I Hate Lazy Commented Nov 4, 2012 at 16:38
  • ah, so have var i = divs.length; i>0; i--? – CJT3 Commented Nov 4, 2012 at 16:40
  • 1 Yes, almost. var i = divs.length - 1; i > -1; i-- – I Hate Lazy Commented Nov 4, 2012 at 16:41
  • ah, brilliant. too bad you didn't post this as an answer. lol – CJT3 Commented Nov 4, 2012 at 16:42
  • @user1689607 Or for ( var i = divs.length - 1; i--; )... – David G Commented Nov 4, 2012 at 16:42
 |  Show 8 more ments

4 Answers 4

Reset to default 6

Because the divs collection is updated when one of its div elements is removed from the DOM, you end up skipping over divs because your i isn't updated with the reindexing of the collection.

A mon solution is to iterate in reverse instead.

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

Another solution you could use is to copy the live HTMLCollection to an inert array, and use your original logic:

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/2UCZa/1/

Yet another solution is to create an Array from an array-like object, and iterate over this. For example:

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

I like this one the best, as it produces the least amount of code, and is very clear!

I don't know why, but this one seemed to work in the end:

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

my loader is basically just a new div, but inside of the div there is this loading symbol, which appears when the content is loaded.

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

So with just this line

ModalBody.insertAdjacentHTML('afterbegin', loader);

...while the content was loaded a got [object HTMLDivElement] shown shortly, after 3 sec more or less the right content appeared. As soon as I added this ".outerHTML" things got right. I am still a super beginner. So, maybe someone could also explaine why this worked?

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745171823a4614972.html

相关推荐

  • Javascript Replace ChildLoop issue - Stack Overflow

    I have this really bizarre issue where I have a forloop that is supposed to replace all divs with the c

    2小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信