John Fouhy
John Fouhy

Reputation: 42203

Removing list elements with Greasemonkey

A blog I read has some annoying commenters. I thought I would try my hand at Greasemonkey to turn them off.

The basic structure of the HTML is simple - a comment looks something like this:

<li>
  <cite>user name ...</cite>
  comment text
</li>

So with that in mind, I bashed my head against the keyboard for a while until this dropped out:

var killlist = /user1|user2/;

var comments = document.getElementsByTagName('li');

if (comments.length) {
  for ( var i = 0; i < comments.length; i ++ ) {
    var comment = comments[i];
    var cites = comment.getElementsByTagName('cite');
    if (cites.length) {
      var cite = cites[0];
      var title = cite.textContent;
      if (killlist.test(title)) {
        comment.parentNode.removeChild(comment);
      }
    }
  }
}

window.alert('Done!')

(the window.alert is just so I know if the script runs to completion)

This mostly works. e.g. on one test page, it removed 13 of 16 posts by one of the users. I tried replacing the removeChild line with this:

comment.style.visibility = 'hidden';

That appears to get everything, but at the expense of leaving great empty spaces where the comments would have been.

I'm a complete javascript newbie, so can anyone see anything obvious I'm doing wrong?

Upvotes: 1

Views: 1498

Answers (2)

Crescent Fresh
Crescent Fresh

Reputation: 117008

The behavior you're seeing is due to comments being a live NodeList. As you remove elements referenced by comments from the DOM, comments is mutated (and its length updated) and your loop goes out the window.

You can loop in reverse order as @Pat suggested, or "unhook" the NodeList from the DOM with a copy operation first:

var comments = Array.slice(document.getElementsByTagName('li'));

Then proceed as before.

Upvotes: 3

Pat
Pat

Reputation: 25685

You should be able to fix it by reversing the order of your for loop and deleting elements from the end of the comments array first:

for ( var i = comments.length - 1; i >= 0; i-- )

Upvotes: 1

Related Questions