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

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

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

98 голосов | спросил Steve 1 Jam1000000amFri, 01 Jan 2010 02:56:25 +030010 2010, 02:56:25

6 ответов


0

Вот решение для вас, использующее только одно очень маленькое и простое изображение и один автоматически сгенерированный элемент 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;
}

Изображение

  

альтернативный текст http://www.ulmanen.fi/stuff/stars.png

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

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();
});

Выход

  

Изображение из набора значков фуги (www.pinvoke.com) http: //www.ulmanen. ц /материал /stars_output.png

Demo

  

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

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


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

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

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

Внешний диапазон получает background-position из 0 -16px

Внутренний диапазон с другой стороны имеет 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));
    });
}
ответил Tatu Ulmanen 1 Jam1000000amFri, 01 Jan 2010 03:09:33 +030010 2010, 03:09:33
0

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

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

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

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

 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>

Затем демонстрация, в которой используется небольшой кусочек кода:

 $(function() {
  function addScore(score, $domElement) {
    $("<span class='stars-container'>")
      .addClass("stars-" + score.toString())
      .text("★★★★★")
      .appendTo($domElement);
  }

  addScore(70, $("#fixture"));
});
 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; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Generated: <div id="fixture"></div>

Самые большие недостатки этого решения:

  1. Вам нужны звезды внутри элемента, чтобы получить правильную ширину;
  2. Нет семантической разметки, например вы бы предпочли score как текст внутри элемента;
  3. Он позволяет набрать столько баллов, сколько у вас будет классов (потому что мы не можем использовать Javascript для точного определения width для псевдоэлемента).

Чтобы исправить это, вышеприведенное решение можно легко настроить. Биты :before и :after должны стать фактические элементы в DOM (поэтому нам нужен JS для этого).

Последнее оставлено в качестве упражнения для читателя.

ответил Jeroen 22 Jpm1000000pmFri, 22 Jan 2016 18:36:31 +030016 2016, 18:36:31
0

Попробуйте эту функцию jquery

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">

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

<script>
    $.fn.stars = function() {
        return $(this).each(function() {

            var rating = $(this).data("rating");

            var numStars = $(this).data("numStars");

            var fullStar = new Array(Math.floor(rating + 1)).join('<i class="fa fa-star"></i>');

            var halfStar = ((rating%1) !== 0) ? '<i class="fa fa-star-half-empty"></i>': '';

            var noStar = new Array(Math.floor(numStars + 1 - rating)).join('<i class="fa fa-star-o"></i>');

            $(this).html(fullStar + halfStar + noStar);

        });
    }

    $('.stars').stars();

 Скриншот

FontAwesome CSS

Вы можете загрузить FontAwesome по адресу http://fontawesome.io/

ответил Rajasekar D 30 AM00000090000005431 2016, 09:55:54
0

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

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

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

ответил paxdiablo 1 Jam1000000amFri, 01 Jan 2010 03:06:39 +030010 2010, 03:06:39
0

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

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

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

ответил Tim Schmidt 29 MaramSun, 29 Mar 2015 05:22:02 +03002015-03-29T05:22:02+03:0005 2015, 05:22:02
0

используя 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);
});

Я также добавил атрибут данных с именем data-rating в промежуток.

<span class="stars" data-rating="4" ></span>
ответил Galuga 27 MarpmFri, 27 Mar 2015 23:02:49 +03002015-03-27T23:02:49+03:0011 2015, 23:02:49

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132