0

http://jsfiddle.net/83m3B/

I want to delete some elements of an array by using data-object-id attribute. But when I use it, the loop does not run as expected. It seems like it jumps over an element every time.

var banIds = ["111", "222", "333"];
function toggle_visibility(className) {
  var elements = document.getElementsByClassName(className),
    n = elements.length;
  for (var i = 0; i < n; i++) {
    var e = elements[i];
    var statusID = e.getAttribute('data-object-id');
    if ($.inArray(statusID, banIds) !== -1) {
      e.remove();
    }
  }
}

What's the problem? And how do I solve it ?

6
  • 1
    Open console and take a look at errors. Commented Jun 15, 2014 at 8:17
  • I don't see where you set 'banIds' Commented Jun 15, 2014 at 8:19
  • The problem is that document.getElementsByClassName(...) returns HTMLCollection - array like object, but not an array ... So it is updated dynamically while you are deleting your elements. Commented Jun 15, 2014 at 8:27
  • @BogdanSavluk, then How should I fix this? Using jquery instead? Commented Jun 15, 2014 at 8:28
  • @cqcn1991: check the answers then. There is one that proposes tiny jquery-based solution Commented Jun 15, 2014 at 8:30

3 Answers 3

3

As soon as jQuery is acceptable there is no reason to not use its facilities:

function toggle_visibility(className) {
    $('.' + className).filter(function() {
        return $.inArray($(this).data('object-id'), banIds) !== -1;
    }).remove();
}
Sign up to request clarification or add additional context in comments.

2 Comments

@cqcn1991: why did you change my code to use .each()? jsfiddle.net/6D6Ly/1 - this is the code that works
I'm not quite familiar with filter, so I change to each making it easier to understand for me. But I'm not sure I get it right.
2

Use while cycle for delete. For cycle skips elements, because they already deleted and other elements have another position index in array.

Or write like this:

if ($.inArray(statusID, banIds) !== -1) {
    e.remove();
    i--;
}

And don't use n, because elements.length changes in cycle.

Comments

0

This is typical error when deleting elements from indexed list.
You are missing fact that when element is deleted all elements after deleted are shifted in index to index-1. So the next element receives same index as deleted one but for loop still increments index and skips one element after deleted.
Simplest way to avoid this problem is to run loop backward:

  for (var i = n-1; i >= 0; i--) {
    var e = elements[i];
    var statusID = e.getAttribute('data-object-id');
    if ($.inArray(statusID, banIds) !== -1) {
      e.remove();
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.