LoginSignup
1
0

More than 5 years have passed since last update.

Star rating like Amazon

Posted at

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

jsFiddle

<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>
.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;
}
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})
  })
}

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0