Reputation: 13275
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
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(""));
}
});
Upvotes: 2