问题
I wrote functions that allow the user to select and de select divs by clicking on them. Now, what i was trying to do was a function that, once pressed a, deselects everything, but it only deselect some of my divs. Here is the code:
var divs = document.getElementsByClassName('fuori');
for(i = 0, j = divs.length; i < j; i++){
divs[i].addEventListener('click', function(){
if(!hasClass(this, 'selected')){
this.className = this.className + " selected";
} else {
removeClass(this, 'selected');
}
});
}
removeClass function is this
function removeClass(ele,cls) {
if (hasClass(ele,cls)) {
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
ele.className=ele.className.replace(reg,' ');
}
}
and this is deselectAll
function deselectAll(){
var selected = document.getElementsByClassName('selected');
alert(selected.length);
for (i = 0; i < selected.length; i++){
removeClass(selected[i], 'selected');
}
}
Selecting and deselecting by clicking works seamlessly, but when i select some divs and press a it doesn't deselect every div, but only some of them.
How could i fix this? and why doesn't it work?
Thank you!
回答1:
Try changing that for
loop:
for (var i = selected.length; --i >= 0; removeClass(selected[i], 'selected'));
The return value from getElementsByClassName()
is a NodeList, not an array, and it's "live". That means that as you change the DOM by removing the class, you're changing the list too.
By going backwards, you avoid the problem. You could also do this:
while (selected.length) removeClass(selected[0], 'selected');
By the way the regex you're using to remove the classes could be simpler:
function removeClass(ele,cls) {
var reg = new RegExp('\\b' + cls + '\\b', 'g');
ele.className=ele.className.replace(reg,' ');
}
In a JavaScript regular expression, \b
means "word boundary". Also there's no point calling hasClass()
because the replacement just won't do anything if the class string isn't present.
edit — It's pointed out in a comment that this doesn't work for class names with embedded hyphens, a common convention. If you need to deal with that, then I think this would work:
function removeClass(ele,cls) {
var reg = new RegExp('\\b' + cls.replace(/-/g, '\\b-\\b') + '\\b', 'g');
ele.className=ele.className.replace(reg,' ');
}
or some variation on that theme.
来源:https://stackoverflow.com/questions/12411561/removeclass-function-doesnt-work-properly