Как построить процентную звездочку, чтобы заполнить десятичный средний рейтинг?

Мне дадут среднюю оценку, например, 4,3, и мне нужно построить логику для отображения средней оценки 4,3 в значке звезды (4 целых звезды,5-я звезда как частично заполненная). Максимальный рейтинг - 5. Я создал jsfiddle, ссылаясь на примеры стека overflow, и я не получаю частичную звезду в моей черновой скрипке, и в результате я получаю всю звезду. Скриншот моего JSFiddle

JSFiddle Ссылка: https://goo.gl/sz1YIJ Пожалуйста, совет.

2 ответа

Обновить:

В ответ на комментарии, есть сотни полезных символов Юникода, которые вы можете скопировать и вставить в свой код, например, ▲ ▼ ★ . Они работают лучше, чем изображения значков, потому что вы можете установить цвет и размер с помощью CSS. Чтобы найти символ, такой как человек в названии ниже, попробуйте поискать таблицу юникода

Простое решение


Кажется, это можно сделать очень просто с помощью чуть-чуть CSS и Javascript.

Здесь у нас есть div с 5 звездами. Мы регулируем ширину, чтобы показать или скрыть звезды. Ключ заключается в том, чтобы использовать скрытые переполнения и стили встроенных блоков, а затем перехватывать clientWidth при инициализации. Это было более надежно, чем использование их единиц или других методов.

Очевидно, вы могли бы улучшить его больше, но я хотел показать минимальный необходимый код.

Запустите фрагмент и введите любое дробное звездное значение от 0 до 5.

var cw = window.rating1.clientWidth; // save original 100% pixel width

function rating( stars ) {
  window.rating1.style.width = Math.round(cw * (stars / 5)) + 'px';
}

rating(4.3);
.rating {
  font-size: 48px;
  color: orange;
  display: inline-block;
  overflow: hidden;
}
.rating::before { 
  content: "★★★★★" 
}
Enter a star rating 0-5: <input onkeyup="rating(this.value)" value="4.3"> 
<p>
<div id="rating1" class="rating"></div>

Я написал функцию, которая делает то, что вам нужно. Он просто устанавливает ширину частичного значка, а переполнение скрыто.

function setFractionalRating(container, value) {
 var floor = Math.floor(value),
   ceil = Math.ceil(value),
   star = container.children[floor],
    slice = Array.prototype.slice,
    children = slice.call(container.children),
    visible = slice.call(children, 0, ceil),
    hidden = slice.call(children, ceil),
   size,
    width,
    portion;
  
  visible.forEach(function(star) {
   star.style.visibility = 'visible';
   star.style.width = '';
  });
  hidden.forEach(function(star) {
   star.style.visibility = 'hidden';
   star.style.width = '';
  });

  size = star && star.getBoundingClientRect();
  width = size && size.width;
  portion = value - floor;

  if (star && portion !== 0)
   star.style.width = (width * portion) + 'px';
}


// Test:
var check = 1,
 debug = document.querySelector('.debug');
debug.appendChild(document.createTextNode(''));
setInterval(function() {
 debug.firstChild.nodeValue = check.toFixed(1);
  setFractionalRating(document.querySelector('.rating'), check);
  if ((check += 0.1) >= 5)
    check = 0.1;
}, 200);
.rating > i {
  display: inline-block;
  overflow: hidden;
}
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="rating">
  <i class="glyphicon glyphicon-star"></i>
  <i class="glyphicon glyphicon-star"></i>
  <i class="glyphicon glyphicon-star"></i>
  <i class="glyphicon glyphicon-star"></i>
  <i class="glyphicon glyphicon-star"></i>
</div>
<div class="debug">
</div>
</div>

Другие вопросы по тегам