Search code examples
javascriptarraysecmascript-6getattribute

How to get values of nodes attributes in an array?


I'm trying to get values of src attribute of images that are in an array, but console shows "item.getAttribute is not a function" error.

HTML

<img src="placeholder.jpg" class="image" data-src="https://mir-s3-cdn-cf.behance.net/project_modules/disp/f474c412850850.56033e5e60fd8.jpg" alt="">
<img src="placeholder.jpg" class="image" data-src="https://i.pinimg.com/originals/2c/09/bd/2c09bdd34dac867792321898f6635e2c.jpg" alt="">
<img src="placeholder.jpg" class="image" data-src="https://i.pinimg.com/originals/a7/e6/9a/a7e69a71125bb231adb1eceb50a60500.jpg" alt="">

JS

let image = document.getElementsByClassName('image');

const images = [];
images.push(image);

(function assignValidSource() {
    const sources = images.map((el) => el.getAttribute('src'));

    // do some other stuff with src later
})();

I can get src value only if checking it for only one element in this array:

const sources = images.map((el) => el[0].getAttribute('src'));

How can I get src values for all images in this array, so I can replace them later with data-src values?


Solution

  • Use Array.from and pass it the HTMLCollection from getElementsByClassName, and use a mapping function (Array.from's second argument) to get the srcs from each element:

    const sources = Array.from(
      document.getElementsByClassName('image'),
      img => img.getAttribute('src')
    );
    console.log(sources);
    <img src="placeholder1.jpg" class="image" data-src="https://mir-s3-cdn-cf.behance.net/project_modules/disp/f474c412850850.56033e5e60fd8.jpg" alt="">
    <img src="placeholder2.jpg" class="image" data-src="https://i.pinimg.com/originals/2c/09/bd/2c09bdd34dac867792321898f6635e2c.jpg" alt="">
    <img src="placeholder3.jpg" class="image" data-src="https://i.pinimg.com/originals/a7/e6/9a/a7e69a71125bb231adb1eceb50a60500.jpg" alt="">

    If you wanted to construct an array from a getElementsByClassName, either use Array.from (just like above, but without the mapping function), or spread it into an array:

    const imageArray = [...document.getElementsByClassName('image')];
    

    or use a plain for loop to push each element to an array:

    const imageArray = [];
    const collection = document.getElementsByClassName('image');
    for (let i = 0; i < collection.length; i++) {
      imageArray.push(collection[i]);
    }
    

    But often you can avoid such intermediate variables by using Array.from or calling an array function like Array.prototype.map:

    const sources = Array.prototype.map.call(
      document.getElementsByClassName('image'),
      img => img.getAttribute('src')
    );
    console.log(sources);
    <img src="placeholder1.jpg" class="image" data-src="https://mir-s3-cdn-cf.behance.net/project_modules/disp/f474c412850850.56033e5e60fd8.jpg" alt="">
    <img src="placeholder2.jpg" class="image" data-src="https://i.pinimg.com/originals/2c/09/bd/2c09bdd34dac867792321898f6635e2c.jpg" alt="">
    <img src="placeholder3.jpg" class="image" data-src="https://i.pinimg.com/originals/a7/e6/9a/a7e69a71125bb231adb1eceb50a60500.jpg" alt="">