javascriptfilterreduceselectors-apigetcomputedstyle

How to target/query exactly the image elements which have their source stored in CSS?


I am using Vite where I store the image's source in the css. In a function, I have to get the source of the image but I am not sure how to pull it from the css. Below is how I selected the img tag and how I stored the img source. How would I write this out in Javascript to put the css content in the array?

// JS
this.images = [...document.querySelectorAll('img')];

//css
#firstimage {
  content: url(./assets/img1.jpg);
}
#secondimage {
  content: url(./assets/img1.jpg);
}

Solution

  • The OP needs to filter each image-element of the queried images-only NodeList (after casting it into an array type) by its computed content style-property with the help of window.getComputedStyle.

    console.log(
      [...document.querySelectorAll('img')]
        .filter(img => {
          // get the computed style object.
          const cs = window.getComputedStyle(img);
          // access the computed `content` value.
          const value = cs.getPropertyValue('content');
          // test whether `value` contains an URL.
          //  - [https://regex101.com/r/j7nccT/1]
          return (/^url\(.+\)$/).test(value);
        })
    );
    #firstimage {
      content: url(https://picsum.photos/67/100?grayscale);
    }
    #secondimage {
      content: url(https://picsum.photos/66/99?grayscale);
    }
    .as-console-wrapper {
      max-height: 90px!important;
    }
    <img id="firstimage" src="" />
    <img src="https://picsum.photos/67/100" />
    <img src="https://picsum.photos/66/99" />
    <img id="secondimage" src="" />

    Edit ... due to the fact that the above (initial) answer missed one (the most important) of the OP's requirements.

    "In a function, I have to get the source of the image but I am not sure how to pull it from the css. ... How would I write this ... to put the css content in the array?"

    The firstly provided solution then needs to be changed from a filter to a reduce task where one (as for the former) not just does test the content value by a simple regex like ... ^url\(.+\)$ ... but also (as for the latter) captures the image-source by a regex like ... ^url\((?<src>.+)\)$ ... which features a named capturing group.

    console.log(
      [...document.querySelectorAll('img')]
        .reduce((result, elm) => {
    
          // get the computed style object.
          const cs = window.getComputedStyle(elm);
    
          // access the computed `content` value.
          const value = cs.getPropertyValue('content');
    
          // test for and capture the image's source.
          //  - [https://regex101.com/r/j7nccT/3]
          const src = (/^url\((?<src>.+)\)$/)
            .exec(value)?.groups?.src ?? null;
    
          if (src !== null) {
            result.push({
              // create an object of element reference and source.
              elm,
              src: src
                // remove possible leading single/double quote.
                .replace(/^['"]/, '')
                // remove possible trailing single/double quote.
                .replace(/['"]$/, '')
            });
          }
          return result;
    
        }, [])
    );
    #firstimage {
      content: url(https://picsum.photos/67/100?grayscale);
    }
    #secondimage {
      content: url(https://picsum.photos/66/99?grayscale);
    }
    .as-console-wrapper {
      max-height: 90px!important;
    }
    <img id="firstimage" src="" />
    <img src="https://picsum.photos/67/100" />
    <img src="https://picsum.photos/66/99" />
    <img id="secondimage" src="" />