-1

I'm just asking myself what is the best way between these two codes to get all element without getting a JS exception.

#1

var items = document.querySelectorAll('.items');
if (!!items) {
  items.forEach(function(item) { 
    item.addEventListener('click', function() { ... })
  }
}

#2

var items = Array.prototype.slice.call(document.querySelectorAll('.items'), 0);
if (items.length > 0) {
  items.forEach(function(item) { 
    item.addEventListener('click', function() { ... })
  }
}

Thank you in advance for your anwsers :)

  • 1
    You don't need `if` condition at all and `querySelectorAll()` returns a node list which as `length` property thus you don't need ` Array.prototype.slice.call` just to use `length` property – Satpal Jul 20 '17 at 12:19
  • what JS exception do you get? – Kaddath Jul 20 '17 at 12:20
  • @charlietfl Yes`.forEach()` can be chained to `.querySelectorAll()` https://stackoverflow.com/questions/36108712/foreach-method-of-node-childnodes – guest271314 Jul 20 '17 at 12:24
  • Thanks, you are right I didn't need the if condition neither checking length – Pierre Marchal Jul 20 '17 at 12:30
  • If you are not experiencing any exceptions and are asking purely hypothetical the answer could well be down to opinion. – Nope Jul 20 '17 at 15:34

2 Answers2

0

You don't need to check the length of an array if you're looping over it, if there aren't any elements in it, nothing will happen.

Note that getElementsByClassName() returns an array-like object, not an actual array, but it does have a length property. See MDN docs.

You could try;

var els = document.getElementsByClassName( 'yourClass' );

for( var i = 0; i < els.length; i++ ){
  els[i].addEventListener( 'click', function(){
    // your code
  });
}
sauntimo
  • 1,531
  • 1
  • 17
  • 28
  • els is not an actual array – charlietfl Jul 20 '17 at 12:23
  • no, its an array-like object, with a length property, right? that's why I've used a for loop, I was just trying to point that out because of what the OP tried to do above. [MDN docs](https://developer.mozilla.org/en/docs/Web/API/Document/getElementsByClassName) - Edited my answer to make this clearer, thanks. – sauntimo Jul 20 '17 at 12:25
0

You can check if "forEach" is in items

var items = document.querySelectorAll('.items');
if (items.length && "forEach" in items) {
  items.forEach(function(item) { 
    item.addEventListener('click', function() { ... })
  })
} else {
  if (items.length && !"forEach" in items) {
    items = Array.prototype.slice.call(document.querySelectorAll('.items'), 0);
    items.forEach(function(item) { 
      item.addEventListener('click', function() { ... })
    })
  }
}

Alternatively, use spread element to make sure we have an array

var items = [...document.querySelectorAll('.items')];
if (items.length) {
  items.forEach(function(item) { 
    item.addEventListener('click', function() { ... })
  })
}

or use for..of loop

for (let item of document.querySelectorAll('.items')) {
  item.addEventListener('click', function() { ... })
}
guest271314
  • 1
  • 15
  • 104
  • 177