8

I have the following javascript code (pure js, no libs), however when its run it only returns one element instead of two

function changeButtonStyles() {
    var actualButtons = document.getElementsByClassName("read-more");
    for (var i = 0; i < actualButtons.length; i++) {
        actualButtons[i].parentNode.className = "basic";
        actualButtons[i].className = "btn btn-xs btn-default";
    }

It should return two elements from the page so I can modify them both, but it only returns the one or the loop only iterates through one. Why is this?

jsfiddle

Colonel Mustard
  • 1,482
  • 2
  • 17
  • 42
  • well you change its initial class so after the click on the top link the function is executed once and then after the click on the bottom link the function doesn't do anything.. – Michail Michailidis Nov 13 '16 at 19:49

1 Answers1

8

Try select all elements by method

document.querySelectorAll(".read-more");

I update fiddle https://jsfiddle.net/rzdkr2gL/7/

And you can use forEach method

actualButtons.forEach(function (el) {
    el.parentNode.className = "basic";
    el.className = "btn btn-xs btn-default";
})

or (recommended way)

Array.prototype.forEach.call(actualButtons, function (el) {
    el.parentNode.className = "basic";
    el.className = "btn btn-xs btn-default";
})

or

NodeList.prototype.forEach.call(actualButtons, function (el) {
    el.parentNode.className = "basic";
    el.className = "btn btn-xs btn-default";
})

Final code may be looks like https://jsfiddle.net/rzdkr2gL/8/

  • 3
    This works because `querySelectorAll` doesn't return a live collection. – 4castle Nov 13 '16 at 19:53
  • Also note that [`forEach`](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach) isn't supported on IE or Safari. – 4castle Nov 13 '16 at 20:03
  • @4castle specifically IE8 and below, partially IE9. But works from IE10 and upward http://caniuse.com/#search=foreach – starcorn Nov 13 '16 at 20:06
  • 1
    `actualButtons.forEach(...` won't work in any browser because `actualButtons` isn't an Array. –  Nov 13 '16 at 20:07
  • @starcorn Right, that's for an array. I was talking about [`NodeList#forEach`](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach) – 4castle Nov 13 '16 at 20:07
  • Look `Array.prototype.forEach` support IE9 and Safari https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach – Dmitrii Korchemkin Nov 13 '16 at 20:10
  • https://jsfiddle.net/rzdkr2gL/9/ Click the `change buttons` link. –  Nov 13 '16 at 20:14
  • @squint Have you tried it? It works for me. – 4castle Nov 13 '16 at 20:14
  • Ok we can use NodeList.prototype.forEach =) – Dmitrii Korchemkin Nov 13 '16 at 20:16
  • @4castle: Are you saying that if you visit the jsfiddle link in the comment directly above yours, and you click the `change buttons` link, you don't get an error? If so, what browser? –  Nov 13 '16 at 20:17
  • @squint I'm using Safari Mobile on my phone. – 4castle Nov 13 '16 at 20:18
  • @4castle: Interesting. Firefox doesn't have it. ...but I see that Chrome does. That's good news. I need to check if it has been standardized. –  Nov 13 '16 at 20:20
  • @squint try in Firefox https://jsfiddle.net/rzdkr2gL/11/ – Dmitrii Korchemkin Nov 13 '16 at 20:24
  • @DmitriKorchemkin: Yes, that works because the `Array.prototype` iteration methods are generic. The direct call isn't available in Firefox yet, and I don't see it in the standard, but it would be nice if it made it in. –  Nov 13 '16 at 20:26