Reputation: 1381
I am finding all the nodes using evaluate() on particular xpath and then I am adding class to highlight those nodes but when i try to remove those classes to unhighlight those nodes its unhighlighting half only. Even the loop runs only half time.
i have made a fiddle to show. Can anybody tell me why is it unhighlighting only half ? HTML part :
<div id="div1">abcdefghi</div>
<div id="div4">abcdefghi</div>
<div id="div2">abcdefghi</div>
<div id="div3">abcdefghi</div>
JS part :
(function xpathTest()
{
var nodesSnapshot = document.evaluate("//div", document, null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
{
nodesSnapshot.snapshotItem(i).classList.add('highlight_csspath_chosen');
}
var ele = document.getElementsByClassName("highlight_csspath_chosen");
for(i=0;i<ele.length;i++)
{
alert(i);
ele[i].classList.remove("highlight_csspath_chosen");
}
})();
CSS part :
.highlight_csspath_chosen{
background-color: #ff8533 !important;
outline: 1px solid #5166bb !important;
}
Upvotes: 0
Views: 668
Reputation: 906
The ele variable is keeping reference of the DOM elements with class highlight_csspath_chosen. So as the loop progresses the length of ele also decreases.
For example,
length of ele is 4 at starting, and i=0
when you remove class from the 1st element, the length becomes 3 and i becomes 1 for next iteration, hence it refers to the 3rd element of the initial array
initial array = [A, B, C, D] and i = 0
class from A is removed,
array is updated to [B, C, D] // since only these elements now contain the class
i is now = 1 , i.e [C] //skipping [B]
therefore in every iteration 1 element is being skipped, hence half of the elements get updated.
check the solution in the fiddle
http://jsfiddle.net/Lrb8j22p/52/
var ele = document.getElementsByClassName("highlight_csspath_chosen");
ele = Array.prototype.slice.call(ele,0);
I have converted the ele into an array so that is doesn't refer to the DOM
Upvotes: 1
Reputation: 164
Javascript document.getElementsByClassName returns a live collection, which means that changes in the DOM are reflected in the collection. So for each iteration, the size of list decreases by 1, so ele.length is not constant. So the loop iterates twice instead of 4 times. You can replace it with a for-each loop.
for(var element : ele){
ele.classList.remove("highlight_csspath_chosen");
}
For more information about live collection refer to Live Collection
Upvotes: 1