cssとjsでレビューの星を動的に作る

基本のHTML

基本のHTMLは以下の通り。

reviewNumの中の数字が変わったら

その数字に合わせてグレーの星をオレンジの星に塗りつぶします。

<p id="reviewNum" class="reviewNum">4</p>

<div class="reviewStar">
  <p class="reviewStar_grey">★★★★★</p>
  <p id="reviewStar_color" class="reviewStar_color">★★★★★</p>
</div>

必要最低限のSASSを書く

*sassで書いているので必要な方はscssに書き換えてください

.reviewStar
  position: relative
  z-index: 0
  display: inline-block
  white-space: nowrap
  &_grey
    color: grey

  &_color
    position: absolute
    z-index: 1
    top: 0
    left: 0
    overflow: hidden
    white-space: nowrap
    color: orange

cssで星を作る考え方

positionプロパティを使って、グレーの星の上にぴったりオレンジ色の星を重ね合わせます。

オレンジ色の星(.reviewStar_color)のwidthを指定することでグレーの星をオレンジ色にするのですが、

sassで指定してしまうと静的になってしまうのでJSで動的にします。

星の数をJSで動的に変化させる

考え方
  1. レビューの評価点数が何点なのかを取得する
  2. オレンジの星のidを取得し、date属性(data-rate)の値を付与する
  3. 星は5点満点なので、widthに評価点数(reviewNum)*20%の計算式を入れてあげる

星を自在にオレンジ色に変える

<script>  
  /* レビュー星 */
  
  //レビューの点数を取得
  var get_reviewNum = document.getElementById("review_num");
  var reviewNum = review_num.textContent;
  //オレンジの星のidを取得
  var review_rating = document.getElementById("reviewStar_color");

  //オレンジの星にdate属性(date-rate)を付与(レビューの点数が入る)
  review_rating.dataset.rate = reviewNum;

  //計算式をつくり、widthに入れる
  review_rating.style.width = reviewNum * 20 + "%";
</script>

この書き方だと、動的に星1から星5まで(0%から100%まで)オレンジの星を自在に操ることができます。(すごい!)

最後にid=”reviewNum”の中の数字を手動で切り替えてみて、正常に動いているか確認しましょう!

星を0.5ずつオレンジ色に変える

うまく書けばもっとコード量は減らせるみたいですが、

現在の私の力では及ばず…( ^ω^ )

グレーの星を0.5刻みでオレンジ色に変化させます。

<script>
  /* レビュー星 */
  var get_reviewNum = document.getElementById("review_num");
  var reviewNum = review_num.textContent;
  var review_rating = document.getElementById("reviewStar_color");

  if (reviewNum < 0.5) {
    review_rating.dataset.rate = 0;
    review_rating.style.width = "0";
  } else if (reviewNum < 1) {
    review_rating.dataset.rate = 0.5;
    review_rating.style.width = "10%";
  } else if (reviewNum < 1.5) {
    review_rating.dataset.rate = 1;
    review_rating.style.width = "20%";
  } else if (reviewNum < 2) {
    review_rating.dataset.rate = 1.5;
    review_rating.style.width = "30%";
  } else if (reviewNum < 2.5) {
    review_rating.dataset.rate = 2;
    review_rating.style.width = "40%";
  } else if (reviewNum < 3) {
    review_rating.dataset.rate = 2.5;
    review_rating.style.width = "50%";
  } else if (reviewNum < 3.5) {
    review_rating.dataset.rate = 3;
    review_rating.style.width = "60%";
  } else if (reviewNum < 4) {
    review_rating.dataset.rate = 3.5;
    review_rating.style.width = "70%";
  } else if (reviewNum < 4.5) {
    review_rating.dataset.rate = 4;
    review_rating.style.width = "80%";
  } else if (reviewNum < 5) {
    review_rating.dataset.rate = 4.5;
    review_rating.style.width = "90%";
  } else if ((reviewNum = 5)) {
    review_rating.dataset.rate = 5;
    review_rating.style.width = "100%";
  }
</script>