Zamień liczbę na wyświetlanie gwiazdek za pomocą jQuery i CSS

Patrzyłem na wtyczkę jquery i zastanawiałem się, jak dostosować tę wtyczkę, aby zamienić numer (jak 4.8618164) w 4.8618164 gwiazdki wypełnione z 5. Zasadniczo interpretując liczbę

Zauważ, że będzie to wyświetlać / pokazywać ocenę gwiazdek tylko z już dostępnego numeru i nie będzie akceptować nowych ocen.

Author: madth3, 2009-12-31

8 answers

Oto rozwiązanie dla ciebie, używając tylko jednego bardzo małego i prostego obrazu i jednego automatycznie generowanego elementu 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;
}

Obraz

alt text
(źródło: ulmanen.fi)

Uwaga: do nie hotlink do powyższego obrazka! Skopiuj plik na własny serwer i użyj go stamtąd.

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

Jeśli chcesz ograniczyć Gwiazdy tylko do połowy lub kwarty rozmiary gwiazd, dodaj jeden z tych wierszy przed var size wiersz:

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>

Użycie

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

Wyjście

Obraz z zestawu ikon fugi (www.pinvoke.com)
(źródło: ulmanen.fi)

Demo

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

To prawdopodobnie będzie pasować do Twoich potrzeb. Dzięki tej metodzie nie musisz obliczać żadnych 3/4 szerokości gwiazd, po prostu daj jej pływak i będzie daj swoje gwiazdki.


Małe wyjaśnienie, jak gwiazdy są przedstawione może być w porządku.

Skrypt tworzy dwa elementy rozpiętości poziomów bloków. Oba przęsła mają rozmiar 80px * 16px i gwiazdkę w tle.png. Są one zagnieżdżone w taki sposób, że struktura przęseł wygląda następująco:

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

Zewnętrzna rozpiętość otrzymuje background-position 0 -16px. To sprawia, że szare gwiazdy na zewnętrznej rozpiętości są widoczne. Ponieważ zewnętrzna rozpiętość ma wysokość 16px i repeat-x, to pokaże tylko 5 szarych gwiazdek.

Wewnętrzna rozpiętość z drugiej strony ma background-position 0 0, co sprawia, że widoczne są tylko żółte gwiazdy.

To oczywiście działa z dwoma oddzielnymi plikami obrazu, star_yellow.png i star_gray.png. Ale ponieważ gwiazdy mają stałą wysokość, możemy łatwo połączyć je w jeden obraz. To wykorzystuje CSS sprite technika.

Teraz, gdy przęsła są zagnieżdżane, są one automatycznie nakładane na siebie. W domyślnym przypadku, gdy szerokość obu przęseł wynosi 80px, żółte gwiazdy całkowicie zasłaniają szare Gwiazdy.

Ale kiedy dostosujemy szerokość wewnętrznej rozpiętości, szerokość żółtych gwiazd maleje, odsłaniając szare Gwiazdy.

Z punktu widzenia dostępności, mądrzej byłoby zostawić numer float wewnątrz wewnętrznej rozpiętości i ukryć go za pomocą text-indent: -9999px, tak aby osoby z wyłączonym CSS zobaczyły przynajmniej liczbę zmiennoprzecinkową zamiast gwiazd.

Mam nadzieję, że to sprawiło, że niektóre sens.


Zaktualizowano 2010/10/22

[14]}teraz jeszcze bardziej zwarty i trudniejszy do zrozumienia! Może być również wyciśnięty do jednej linijki:
$.fn.stars = function() {
    return $(this).each(function() {
        $(this).html($('<span />').width(Math.max(0, (Math.min(5, parseFloat($(this).html())))) * 16));
    });
}
 255
Author: Tatu Ulmanen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-26 19:07:35

Jeśli musisz tylko obsługiwać nowoczesne przeglądarki, możesz uciec od:

  • No images;
  • głównie statyczny css;
  • prawie brak jQuery lub Javascript;

Wystarczy zamienić liczbę na class, np. class='stars-score-50'.

Pierwsze demo "renderowanych" znaczników:

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>

Potem demo, które wykorzystuje trochę kod:

$(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>

Największymi wadami tego rozwiązania są:

  1. do wygenerowania prawidłowej szerokości potrzebne są gwiazdki wewnątrz elementu;
  2. nie ma znaczników semantycznych, np. wolisz wynik jako tekst wewnątrz elementu;
  3. pozwala tylko na tyle punktów, ile będziesz miał klas (ponieważ nie możemy użyć Javascript, aby ustawić dokładny width na pseudo-elemencie).

Aby to naprawić powyższe rozwiązanie można łatwo dostosować. Bity :before i :after muszą stać się rzeczywistymi elementami w DOM (więc potrzebujemy do tego trochę JS).

[[10]}Ten ostatni jest pozostawiony jako ćwiczenie dla czytelnika.
 34
Author: Jeroen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-22 15:36:31

Spróbuj użyć funkcji / pliku jQuery helper

Jquery.Ocena.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}`);
    });
}

Indeks.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>

Zrzut ekranu

 25
Author: Rajasekar D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-28 11:46:13

Dlaczego po prostu nie mieć pięciu oddzielnych obrazów Gwiazdy (pustych, pełnych, pół pełnych, trzech pełnych i pełnych), a następnie po prostu wstrzyknąć obrazy do domu w zależności od obciętej lub roudowanej wartości oceny pomnożonej przez 4 (Aby uzyskać całą cyfrę dla kwartałów)?

Na przykład, 4.8618164 pomnożone przez 4 i zaokrąglone wynosi 19, co oznaczałoby cztery i trzy czwarte gwiazd.

Alternatywnie (jeśli jesteś leniwy jak ja), wystarczy wybrać jedno zdjęcie z 21 (0 gwiazdek do 5 gwiazdek w krokach co jedną czwartą) i wybrać pojedynczy obraz na podstawie wyżej wymienionej wartości. Następnie jest to tylko jedno obliczenie, a następnie zmiana obrazu w DOM (zamiast próbować zmienić pięć różnych obrazów).

 7
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-01 00:41:32

Skończyłem całkowicie wolny od JS, aby uniknąć opóźnienia renderowania po stronie klienta. Aby to osiągnąć, generuję HTML w ten sposób:

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

Aby pomóc w dostępności, dodaję nawet raw rating value w atrybucie title.

 5
Author: Tim Schmidt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-29 02:22:02

Używając jquery bez prototype, zaktualizuj kod js do

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

Dodałem również atrybut data o nazwie Data-rating w span.

<span class="stars" data-rating="4" ></span>
 4
Author: Galuga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-27 20:16:11

DEMO

Możesz to zrobić tylko z 2 obrazami. 1 puste Gwiazdy, 1 wypełnione Gwiazdy.

Nakładka wypełniona obrazem na górze drugiego. i przekonwertuj liczbę ocen na procent i użyj jej jako szerokości obrazu wypełniacza.

Tutaj wpisz opis obrazka

.containerdiv {
  border: 0;
  float: left;
  position: relative;
  width: 300px;
} 
.cornerimage {
  border: 0;
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
 } 
 img{
   max-width: 300px;
 }
 3
Author: Elyor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-11 07:47:29

Oto moje podejście do JSX i font awesome, ograniczone tylko .5 trafność:

       <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>

Pierwszy rząd jest dla całej gwiazdy, a drugi rząd jest dla półgwiazdki (jeśli istnieje)

 0
Author: Ardhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-31 15:25:44