Sven
Sven

Reputation: 13275

JavaScript: For-Loop not working properly

I got the following code (I got it from here ):

$( "p" ).children().andSelf().contents().each( function () {
  if ( this.nodeType == 3 ) {
    var $this = $( this );
    var regEx = /(\w)/g;

    for(i = 0; i < 5; i++){
      $this.replaceWith( $this.text().replace( regEx, "<span class='numbers"+ i +"'>$&</span>" ));
     }
   }
});

It's part of a function that is working fine. Only when I add that for-Loop it fails.

The Problem: When I console.log(i) it increments as expected. When I alert(i), it alerts 0-4 for six times. Also, i isn't added to the numberX class. Looking at the DOM, i is always zero. What's wrong with the loop?

Upvotes: 0

Views: 945

Answers (1)

Alvin Wong
Alvin Wong

Reputation: 12420

In your for loop when i==0, this in the DOM has been replaced by your new <span> element, but in JavaScript context, this still refers to your original element. That's why further replacement won't work and the class is stuck at 0.

Let's say for example your original element is a <div>:

i     | this  | The same place in DOM
======|=======|======================================
-     | <div> | <div>
0     | <div> | replaced by <span class="number0">
1...5 | <div> | <span class="number0"> (not affected)

Because after i==0, this is already off the DOM. So further replacement don't work.

A way to correct your code will be:

$("div").children().andSelf().contents().each(function(index,item){
    if (this.nodeType == 3) {
        var $this = $(item);
        var arr=$this.text().match(/(\w)/g);
        arr.forEach(function(item,i,a){a[i]=item.replace(/(.*)/, "<span class='number"+i+"'>$&</span>");});
        $this.replaceWith(arr.join(""));
    }
});

http://jsfiddle.net/KVm9C/

Upvotes: 2

Related Questions