[英]Turn a number into star rating display using jQuery and CSS
我一直在尋找jquery插件,並想知道如何調整該插件將數字(如4.8618164)轉換為4.8618164星星填充5.基本上將數字<5轉換為使用jQuery填充在5星評級系統中的星號/ JS / CSS。
請注意,這只會顯示/顯示已經可用數字的星級,而不接受新的評級提交。
這里有一個解決方案,只使用一個非常小而簡單的圖像和一個自動生成的span元素:
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 )
注意: 請勿鏈接到上面的圖片! 將文件復制到您自己的服務器並從那里使用它。
$.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 */
<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();
});
(來源: ulmanen.fi )
這可能會滿足您的需求。 使用這種方法,您不必計算任何三分之一或任何星形寬度,只需給它一個浮點數,它就會給你你的星星。
關於星星如何呈現的一個小解釋可能是有序的。
該腳本創建兩個塊級跨度元素。 兩個跨度最初的尺寸為80px * 16px,背景圖像為stars.png。 跨度是嵌套的,因此跨度的結構如下所示:
<span class="stars">
<span></span>
</span>
外跨度的background-position
為0 -16px
。 這使得外跨度中的灰色星可見。 由於外跨度高度為16px和repeat-x
,因此它只顯示5顆灰色恆星。
另一方面,內跨度具有0 0
的background-position
,這使得僅黃色星可見。
這當然適用於兩個獨立的圖像文件,star_yellow.png和star_gray.png。 但由於恆星具有固定的高度,我們可以輕松地將它們組合成一個圖像。 這利用了CSS精靈技術 。
現在,當跨度嵌套時,它們會自動疊加在一起。 在默認情況下,當兩個跨度的寬度為80px時,黃色星星完全遮蔽灰色星星。
但是當我們調整內跨的寬度時,黃色恆星的寬度會減小,從而顯示出灰色的恆星。
可訪問性方面,將浮點數保留在內部范圍內並使用text-indent: -9999px
隱藏它是明智的text-indent: -9999px
,因此關閉CSS的人至少會看到浮點數而不是星號。
希望這有點道理。
現在更緊湊,更難理解! 也可以擠到一個襯里:
$.fn.stars = function() {
return $(this).each(function() {
$(this).html($('<span />').width(Math.max(0, (Math.min(5, parseFloat($(this).html())))) * 16));
});
}
如果您只需要支持現代瀏覽器,您就可以逃脫:
您只需要將數字轉換為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>
該解決方案的最大缺點是:
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>
您只能使用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.