簡體   English   中英

使用jQuery和CSS將數字轉換為星級評分顯示

[英]Turn a number into star rating display using jQuery and CSS

我一直在尋找jquery插件,並想知道如何調整該插件將數字(如4.8618164)轉換為4.8618164星星填充5.基本上將數字<5轉換為使用jQuery填充在5星評級系統中的星號/ JS / CSS。

請注意,這只會顯示/顯示已經可用數字的星級,而不接受新的評級提交。

這里有一個解決方案,只使用一個非常小而簡單的圖像和一個自動生成的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;
}

圖片

替代文字
(來源: 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();
});

產量

來自fugue icon set的圖片(www.pinvoke.com)
(來源: ulmanen.fi

演示

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

這可能會滿足您的需求。 使用這種方法,您不必計算任何三分之一或任何星形寬度,只需給它一個浮點數,它就會給你你的星星。


關於星星如何呈現的一個小解釋可能是有序的。

該腳本創建兩個塊級跨度元素。 兩個跨度最初的尺寸為80px * 16px,背景圖像為stars.png。 跨度是嵌套的,因此跨度的結構如下所示:

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

外跨度的background-position0 -16px 這使得外跨度中的灰色星可見。 由於外跨度高度為16px和repeat-x ,因此它只顯示5顆灰色恆星。

另一方面,內跨度具有0 0background-position ,這使得僅黃色星可見。

這當然適用於兩個獨立的圖像文件,star_yellow.png和star_gray.png。 但由於恆星具有固定的高度,我們可以輕松地將它們組合成一個圖像。 這利用了CSS精靈技術

現在,當跨度嵌套時,它們會自動疊加在一起。 在默認情況下,當兩個跨度的寬度為80px時,黃色星星完全遮蔽灰色星星。

但是當我們調整內跨的寬度時,黃色恆星的寬度會減小,從而顯示出灰色的恆星。

可訪問性方面,將浮點數保留在內部范圍內並使用text-indent: -9999px隱藏它是明智的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));
    });
}

如果您只需要支持現代瀏覽器,您就可以逃脫:

  • 沒有圖像;
  • 主要是靜態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. 沒有語義標記,例如,您更喜歡將分數作為元素內的文本;
  3. 它只允許你有類的分數(因為我們不能使用Javascript在偽元素上設置精確的width )。

為了解決這個問題,可以輕松調整上述解決方案。 :before:after位需要成為DOM中的實際元素(因此我們需要一些JS)。

后者留給讀者作為練習。

試試這個jquery helper函數/文件

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>

截圖

為什么不只有一個星形的五個單獨圖像(空,四分之一滿,半滿,三分之四滿和全),然后根據等級的截斷或粗略值乘以4將圖像注入到DOM中(獲得整個季度的數量)?

例如,4.8618164乘以4並且舍入為19,這將是四分之三和四分之三的星。

或者(如果你像我一樣懶惰),只需從21中選擇一個圖像(0星到5星,以四分之一為增量),並根據上述值選擇單個圖像。 然后它只是一個計算,然后是DOM中的圖像更改(而不是嘗試更改五個不同的圖像)。

我最終完全沒有JS,以避免客戶端渲染延遲。 為此,我生成這樣的HTML:

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

為了幫助提高可訪問性,我甚至在title屬性中添加原始評級值。

使用沒有原型的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中添加了數據評級名稱的數據屬性。

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

DEMO

您只能使用2張圖片。 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;
 }

這是我使用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>

第一排是整星,第二排是半星(如果有的話)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM