Star rating like Amazon

If there is a good writing method, please tell me.

[jsFiddle](https://jsfiddle.net/ghost7492/ktdgLaev/1/)

```html
<div class="wrap">
    <div class="review-wrap">
      <div class="star-wrap">
        <div class="star bigStar" data-rating="1"></div>
        <div class="star bigStar" data-rating="2"></div>
        <div class="star bigStar" data-rating="3"></div>
        <div class="star bigStar" data-rating="4"></div>
        <div class="star bigStar" data-rating="5"></div>
      </div>
      <div class="review-text-wrap">
        <span id="review-text"></span>
      </div>
    </div>
  </div>
```
```css
.wrap {
  display: flex;
  justify-content: center;
  width: 800px;
  height: 800px;
  margin: 0 auto;
}
.review-wrap {
  display: inherit;
  height: 45px;
}
.star-wrap {
  display: inherit;
}

.bigStar, .blueStar {
  background: url(https://images-na.ssl-images-amazon.com/images/G/01/x-locale/common/customer-reviews/RYP_mobile_spritex2-v8._V316463287_.png) no-repeat;
  width: 46px;
  height: 45px;
}

.review-text-wrap{
  display: flex;
  justify-content: start;
  align-items: center;
  margin-left: 10px;
  width: 120px;
  font-size: 0.9rem;
  font-weight: 700;
}

.bigStar {
  background-position: -6px -387px;
  background-size: 326px 550px;
}

.blueStar {
  background-position: -51px -387px;
  background-size: 326px 550px;
}

.yellowStar {
  background-position: -96px -387px;
  background-size: 326px 550px;
}
```
```javascript
const $starList = document.getElementsByClassName('star')
const $reviewText = document.getElementById('review-text')
const starList = Array.from($starList)
const reviewTextList = ['全く気に入らない', '気に入らない', '普通', '気に入った', 'とても気に入った']
const getReviewText = ({starRatingNum}) => {
  return reviewTextList[starRatingNum - 1]
}
const HTML_CLASS = {
  BLUE_STAR: 'blueStar',
  YELLOW_STAR: 'yellowStar'
}

const classReplaceStarList = {
  whenClick: ({ starRatingNum }) => {
    starList.forEach((star, idx) => {
      if (idx < starRatingNum) {
        star.classList.replace(HTML_CLASS.BLUE_STAR, HTML_CLASS.YELLOW_STAR)
      }
      if (star.hadYellowStar) star.hadYellowStar = false
    })
  },
  whenMouseover: ({ starRatingNum }) => {
    starList.forEach((star, idx) => {
      if (idx < starRatingNum) star.classList.add(HTML_CLASS.BLUE_STAR)
      if (star.classList.contains(HTML_CLASS.YELLOW_STAR)) {
        star.classList.remove(HTML_CLASS.YELLOW_STAR)
        star.hadYellowStar = true
      }
    })
  },
  whenMouseleave: ({ starRatingNum }) => {
    starList.forEach((star, idx) => {
      if (idx < starRatingNum) star.classList.remove(HTML_CLASS.BLUE_STAR)
      if (star.hadYellowStar) star.classList.add(HTML_CLASS.YELLOW_STAR)
    })
  },
}

for (const $star of $starList) {
  $star.addEventListener('click', () => {
    const starRatingNum = parseInt($star.dataset.rating)
    classReplaceStarList.whenClick({starRatingNum})
  })
  $star.addEventListener('mouseover', () => {
    const starRatingNum = parseInt($star.dataset.rating)
    $reviewText.innerHTML = getReviewText({starRatingNum})
    classReplaceStarList.whenMouseover({starRatingNum})
  })
  $star.addEventListener('mouseleave', () => {
    const starRatingNum = parseInt($star.dataset.rating)
    $reviewText.innerHTML = ''
    classReplaceStarList.whenMouseleave({starRatingNum})
  })
}

```