Поверните число в звездный дисплей, используя jQuery и CSS

Я смотрел плагин jquery и задавался вопросом, как адаптировать этот плагин, чтобы превратить число (например, 4.8618164) в звезды 4.8618164, заполненные из 5. В основном интерпретация числа < 5 в звезды, заполненные 5-звездочным с помощью jQuery/JS/CSS.

Обратите внимание, что это будет отображать/показывать только рейтинг звезд с уже доступного номера и не принимать новые заявки на рейтинги.

Ответ 1

Вот решение для вас, используя только одно очень маленькое и простое изображение и один автоматически сгенерированный элемент span:

CSS

span.stars, span.stars span {
    display: block;
    background: url(stars.png) 0 -16px repeat-x;
    width: 80px;
    height: 16px;
}

span.stars span {
    background-position: 0 0;
}

Образ

alt text
(источник: ulmanen.fi)

Примечание: НЕ используйте горячую ссылку на изображение выше! Скопируйте файл на свой сервер и используйте его оттуда.

JQuery

$.fn.stars = function() {
    return $(this).each(function() {
        // Get the value
        var val = parseFloat($(this).html());
        // Make sure that the value is in 0 - 5 range, multiply to get width
        var size = Math.max(0, (Math.min(5, val))) * 16;
        // Create stars holder
        var $span = $('<span />').width(size);
        // Replace the numerical value with stars
        $(this).html($span);
    });
}

Если вы хотите ограничить размеры звезд только половиной или четвертью звезды, добавьте одну из этих строк перед строкой var size переменной:

val = Math.round(val * 4) / 4; /* To round to nearest quarter */
val = Math.round(val * 2) / 2; /* To round to nearest half */

HTML

<span class="stars">4.8618164</span>
<span class="stars">2.6545344</span>
<span class="stars">0.5355</span>
<span class="stars">8</span>

использование

$(function() {
    $('span.stars').stars();
});

Выход

Image from fugue icon set (www.pinvoke.com)
(источник: ulmanen.fi)

демонстрация

http://www.ulmanen.fi/stuff/stars.php

Это, вероятно, подойдет вашим потребностям. С помощью этого метода вам не нужно вычислять ширину звезды в три четверти или даже больше, просто дайте ей число с плавающей точкой, и она даст вам ваши звезды.


Небольшое объяснение того, как представлены звезды, может быть в порядке.

Скрипт создает два элемента span уровня блока. Оба пролета изначально получают размер 80px * 16px и фоновое изображение stars.png. Пролеты являются вложенными, поэтому структура пролетов выглядит следующим образом:

<span class="stars">
    <span></span>
</span>

Внешний промежуток получает background-position 0 -16px. Это делает серые звезды во внешнем пролете видимыми. Поскольку внешний промежуток имеет высоту 16px и repeat-x, он покажет только 5 серых звезд.

Внутренний промежуток с другой стороны имеет положение background-position 0 0 что делает видимыми только желтые звезды.

Это, конечно, будет работать с двумя отдельными файлами изображений, star_yellow.png и star_gray.png. Но так как звезды имеют фиксированную высоту, мы можем легко объединить их в одно изображение. Это использует технику спрайта CSS.

Теперь, когда промежутки вложены, они автоматически накладываются друг на друга. В случае по умолчанию, когда ширина обоих участков составляет 80 пикселей, желтые звезды полностью затеняют серые звезды.

Но когда мы регулируем ширину внутреннего пролета, ширина желтых звезд уменьшается, обнажая серые звезды.

Что касается доступности, было бы разумнее оставить число с плавающей точкой во внутреннем интервале и скрыть его с text-indent: -9999px, чтобы люди с отключенным CSS могли по крайней мере видеть число с плавающей запятой вместо звездочек.

Надеюсь, это имело смысл.


Обновлено 2010/10/22

Теперь еще компактнее и сложнее для понимания! Можно также сжать до одного вкладыша:

$.fn.stars = function() {
    return $(this).each(function() {
        $(this).html($('<span />').width(Math.max(0, (Math.min(5, parseFloat($(this).html())))) * 16));
    });
}

Ответ 2

Если вам нужно только поддерживать современные браузеры, вы можете уйти с:

  • Нет изображений;
  • В основном статический css;
  • Почти нет jQuery или Javascript;

Вам нужно только преобразовать число в class, например. class='stars-score-50'.

Сначала демонстрационная разметка "rendered":

body { font-size: 18px; }

.stars-container {
  position: relative;
  display: inline-block;
  color: transparent;
}

.stars-container:before {
  position: absolute;
  top: 0;
  left: 0;
  content: '★★★★★';
  color: lightgray;
}

.stars-container:after {
  position: absolute;
  top: 0;
  left: 0;
  content: '★★★★★';
  color: gold;
  overflow: hidden;
}

.stars-0:after { width: 0%; }
.stars-10:after { width: 10%; }
.stars-20:after { width: 20%; }
.stars-30:after { width: 30%; }
.stars-40:after { width: 40%; }
.stars-50:after { width: 50%; }
.stars-60:after { width: 60%; }
.stars-70:after { width: 70%; }
.stars-80:after { width: 80%; }
.stars-90:after { width: 90%; }
.stars-100:after { width: 100; }
Within block level elements:

<div><span class="stars-container stars-0">★★★★★</span></div>
<div><span class="stars-container stars-10">★★★★★</span></div>
<div><span class="stars-container stars-20">★★★★★</span></div>
<div><span class="stars-container stars-30">★★★★★</span></div>
<div><span class="stars-container stars-40">★★★★★</span></div>
<div><span class="stars-container stars-50">★★★★★</span></div>
<div><span class="stars-container stars-60">★★★★★</span></div>
<div><span class="stars-container stars-70">★★★★★</span></div>
<div><span class="stars-container stars-80">★★★★★</span></div>
<div><span class="stars-container stars-90">★★★★★</span></div>
<div><span class="stars-container stars-100">★★★★★</span></div>

<p>Or use it in a sentence: <span class="stars-container stars-70">★★★★★</span> (cool, huh?).</p>

Ответ 3

Попробуйте эту вспомогательную функцию/файл jquery

jquery.Rating.js

//ES5
$.fn.stars = function() {
    return $(this).each(function() {
        var rating = $(this).data("rating");
        var fullStar = new Array(Math.floor(rating + 1)).join('<i class="fas fa-star"></i>');
        var halfStar = ((rating%1) !== 0) ? '<i class="fas fa-star-half-alt"></i>': '';
        var noStar = new Array(Math.floor($(this).data("numStars") + 1 - rating)).join('<i class="far fa-star"></i>');
        $(this).html(fullStar + halfStar + noStar);
    });
}

//ES6
$.fn.stars = function() {
    return $(this).each(function() {
        const rating = $(this).data("rating");
        const numStars = $(this).data("numStars");
        const fullStar = '<i class="fas fa-star"></i>'.repeat(Math.floor(rating));
        const halfStar = (rating%1!== 0) ? '<i class="fas fa-star-half-alt"></i>': '';
        const noStar = '<i class="far fa-star"></i>'.repeat(Math.floor(numStars-rating));
        $(this).html('${fullStar}${halfStar}${noStar}');
    });
}

index.html

   <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Star Rating</title>
        <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" rel="stylesheet">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <script src="js/jquery.Rating.js"></script>
        <script>
            $(function(){
                $('.stars').stars();
            });
        </script>
    </head>
    <body>

        <span class="stars" data-rating="3.5" data-num-stars="5" ></span>

    </body>
    </html>

Screenshot

Ответ 4

Почему бы просто не разделить пять отдельных изображений звезды (пустое, четверть-полное, полуполное, три четверти полного и полного), а затем просто вставлять изображения в DOM в зависимости от усеченного или намазанного значения умножения на 4 (чтобы получить целое число для кварталов)?

Например, 4.8618164, умноженное на 4 и округленное, равно 19, что будет четыре и три четверти звезды.

В качестве альтернативы (если вы ленивы, как я), просто выберите одно изображение из 21 (0 звезд по 5 звезд с шагом в одну четверть) и выберите одно изображение на основе вышеупомянутого значения. Затем это всего лишь один расчет, за которым следует изменение изображения в DOM (вместо того, чтобы пытаться изменить пять разных изображений).

Ответ 5

В итоге я полностью освободился от JS, чтобы избежать задержки на стороне клиента. Для этого я генерирую HTML следующим образом:

<span class="stars" title="{value as decimal}">
    <span style="width={value/5*100}%;"/>
</span>

Чтобы помочь с доступностью, я даже добавляю исходное значение рейтинга в атрибуте title.

Ответ 6

используя jquery без прототипа, обновите код js до

$( ".stars" ).each(function() { 
    // Get the value
    var val = $(this).data("rating");
    // Make sure that the value is in 0 - 5 range, multiply to get width
    var size = Math.max(0, (Math.min(5, val))) * 16;
    // Create stars holder
    var $span = $('<span />').width(size);
    // Replace the numerical value with stars
    $(this).html($span);
});

Я также добавил атрибут данных по имени рейтинга данных в диапазоне.

<span class="stars" data-rating="4" ></span>

Ответ 7

DEMO

Вы можете сделать это только с двумя изображениями. 1 пустые звезды, 1 заполненные звезды.

Наложение заполненного изображения на верхнюю часть другого. и преобразовать рейтинг в процентах и ​​использовать его в качестве ширины изображения заполнения.

введите описание изображения здесь

.containerdiv {
  border: 0;
  float: left;
  position: relative;
  width: 300px;
} 
.cornerimage {
  border: 0;
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
 } 
 img{
   max-width: 300px;
 }

Ответ 8

Вот мой пример использования JSX и шрифта, ограниченный только точностью .5, хотя:

       <span>
          {Array(Math.floor(rating)).fill(<i className="fa fa-star"></i>)}
          {(rating) - Math.floor(rating)==0 ? ('') : (<i className="fa fa-star-half"></i>)}
       </span>

Первый ряд для всей звезды, а второй ряд для половины звезды (если есть)