Как построить процентную звездочку, чтобы заполнить десятичный средний рейтинг?
Мне дадут среднюю оценку, например, 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>