Звездная система рейтинга, нужно дважды щелкнуть, чтобы выделить ее - PullRequest
0 голосов
/ 04 мая 2020

У меня проблема с моей системой оценки по звездам. Звездный рейтинг функционирует хорошо, но звезда будет выделена только тогда, когда я нажму на нее дважды. Например, если я хочу оценить 3/5, мне нужно будет щелкнуть звездочку 3 дважды, чтобы она была выделена. Как мне сделать это одним кликом? :/ Спасибо!

function firstRating() {
  const star = document.querySelector(".rating").children;

  for (let i = 0; i < star.length; i++) {
    star[i].addEventListener("click", function() {
      for (let j = 0; j < star.length; j++) {
        star[j].classList.remove("fa", "fa-star-o");
        star[j].classList.add("fa", "fa-star");
      }

      for (let j = 0; j <= i; j++) {
        star[j].classList.remove("fa", "fa-star-o");
        star[j].classList.add("fa", "fa-star");
      }
    });
  }
}

function secondRating() {
  const star = document.querySelector(".rating_2").children;

  for (let i = 0; i < star.length; i++) {
    star[i].addEventListener("click", function() {
      for (let j = 0; j < star.length; j++) {
        star[j].classList.remove("fa", "fa-star-o");
        star[j].classList.add("fa", "fa-star");
      }

      for (let j = 0; j <= i; j++) {
        star[j].classList.remove("fa", "fa-star-o");
        star[j].classList.add("fa", "fa-star");
      }
    });
  }
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>


<div class="form-group" onclick="firstRating()">
  <label class="col-lg-5 col-md-4 control-label" for="firstRating">Experience</label>
  <div class="rating col-lg-7" style="float: right">
    <input type="hidden" name="rating_1" id="rating_1" value="0" />
    <span class="fa fa-star-o" id="rate1"></span>
    <span class="fa fa-star-o" id="rate2"></span>
    <span class="fa fa-star-o" id="rate3"></span>
    <span class="fa fa-star-o" id="rate4"></span>
    <span class="fa fa-star-o" id="rate5"></span>
  </div>
</div>

<div class="form-group" onclick="secondRating()">
  <label class="col-lg-5 col-md-4 control-label" for="secondRating">Speed</label>
  <div class="rating_2 col-lg-7" style="float: right">
    <input type="hidden" name="rating_2" id="rating_2" value="0" />
    <span class="fa fa-star-o" id="ratee1"></span>
    <span class="fa fa-star-o" id="ratee2"></span>
    <span class="fa fa-star-o" id="ratee3"></span>
    <span class="fa fa-star-o" id="ratee4"></span>
    <span class="fa fa-star-o" id="ratee5"></span>
  </div>
</div>

1 Ответ

1 голос
/ 05 мая 2020

Я не уверен, что идет не так, но, глядя на ваш код, я бы предложил некоторые изменения. Вам следует избегать дублирования функций (например, firstRating (), secondRating () ...) -> что делать, если на вашей странице было 30 разных оценок? Кроме того, ваш HTML сложно построить (id = ratee1, ratee2 ....) - что если у вас было 7 звезд на 30 различных рейтингов? Можете ли вы использовать это на другой странице / проекте?

Попробуйте создать шаблон HTML для того, что вам нужно повторить на своей странице, затем создайте функцию, которая использует этот шаблон для генерации чего-либо.

Вот пример:

function initStarRating() {
  var attrName = "starRating",
    list = document.querySelectorAll('input[' + attrName + ']');

  var buildStarGroup = function(el) {

    var parent = el.parentNode,
      class_0 = el.getAttribute("class-0"),
      class_1 = el.getAttribute("class-1"),
      num_stars = el.getAttribute("num-stars");

    el.type = "hidden";
    el.name = el.getAttribute(attrName);
    el.removeAttribute(attrName);

    parent.stars = [];

    for (let j = 1; j <= num_stars; j++) {
      let input = document.createElement("i");
      input.className = j <= el.value ? class_1 : class_0;
      input.value = j;
      parent.appendChild(input);
      parent.stars.push(input);
    }

    parent.onclick = function(e) {
      if (parent.stars.indexOf(e.target) < 0)
        return;
      el.value = e.target.value;
      for (let i = 0; i < parent.stars.length; i++)
        if (i < el.value)
          parent.stars[i].className = class_1;
        else
          parent.stars[i].className = class_0;
    }
  }

  for (let i = 0; i < list.length; i++) {
    buildStarGroup(list[i]);
  }
}
/** initialize stars **/
initStarRating();
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />

<div class="form-group">
  <label class="col-lg-5 col-md-4 control-label" for="firstRating">Experience</label>
  <div class="rating col-lg-7" style="float: right">
    <input starRating="rating_1" num-stars="5" value="1" class-0="fa fa-star-o" class-1="fa fa-star" />
  </div>
</div>

<div class="form-group">
  <label class="col-lg-5 col-md-4 control-label" for="secondRating">Speed</label>
  <div class="rating col-lg-7" style="float: right">
    <input starRating="rating_2" num-stars="5" value="3" class-0="fa fa-star-o" class-1="fa fa-star" />
  </div>
</div>

Я уверен, что этот код можно улучшить, но он работает и должен дать вам возможность начать создавать свои собственные шаблоны. Ура! * * 1013

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...