javascriptsvgvariable-length

Can you get .length of number of svgs to create a rating score?


Not sure if this is doable, but is there a way you can use .length or another method to get the rating score of something which is usually displayed in svg form?

In the below HTML in each svg there's a "g fill" which determines what is outputted.

Is there a way to use .length here to determine what the rating is? This should be 3.5 stars in this case.

document.querySelector(".productRating").insertAdjacentHTML("afterend", "Review is: " + document.querySelectorAll('.productStar').length);
<div class="productRating">
  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">
    <g fill="var(--review-star-active)">
    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>
    </g></svg>
  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">
  <g fill="var(--review-star-active)">
    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>
    </g></svg>
  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">
  <g fill="var(--review-star-active)">
    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>
    </g></svg>
  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">
  <g fill="url('#57_rating-half-star')">
    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>
    </g></svg>
  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">
  <g fill="var(--review-star-inactive)">
    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>
    </g></svg>
</div>


Solution

  • You can select the g elements directly, convert the returned NodeList to an array (here using spread syntax) and filter() it by the fill attribute; once for the full stars and again for the half stars.

    const stars = [...document.querySelectorAll('.productStar g')];
    
    const fullCount = stars.filter(g =>
      g.getAttribute('fill') === 'var(--review-star-active)').length;
    
    const halfCount = stars.filter(g =>
      g.getAttribute('fill').includes('half-star')).length;
    
    console.log(fullCount + halfCount / 2);
    <div class="productRating">  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">    <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="url('#57_rating-half-star')">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-inactive)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg></div>

    ES5

    var stars = [].slice.call(document.querySelectorAll('.productStar g'));
    
    var fullCount = stars.filter(function (g) {
      return g.getAttribute('fill') === 'var(--review-star-active)';
    }).length;
    
    var halfCount = stars.filter(function (g) {
      return g.getAttribute('fill').indexOf('half-star') !== -1;
    }).length;
    
    console.log(fullCount + halfCount / 2);
    <div class="productRating">  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">    <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="url('#57_rating-half-star')">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-inactive)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg></div>

    Example iterating over each productRating

    var ratings = document.querySelectorAll('.productRating');
    
    ratings.forEach(function (rating) {
      var stars = [].slice.call(rating.querySelectorAll('.productStar g'));
    
      var fullCount = stars.filter(function (g) {
        return g.getAttribute('fill') === 'var(--review-star-active)';
      }).length;
    
      var halfCount = stars.filter(function (g) {
        return g.getAttribute('fill').indexOf('half-star') !== -1;
      }).length;
    
      rating.insertAdjacentHTML("afterend", "Review is: " + (fullCount + halfCount / 2));
    });
    <div class="productRating">  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">    <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="url('#57_rating-half-star')">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-inactive)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg></div>
    
    <div class="productRating">  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">    <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-active)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="url('#57_rating-half-star')">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-inactive)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg>  <svg class="productStar" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 17" width="18" height="18">  <g fill="var(--review-star-inactive)">    <polygon points="9 13.5 3.70993273 16.2811529 4.72024568 10.3905765 0.440491353 6.21884705 6.35496636 5.35942353 9 0 11.6450336 5.35942353 17.5595086 6.21884705 13.2797543 10.3905765 14.2900673 16.2811529"></polygon>    </g></svg></div>