私はjqueryプラグインを見ていましたが、そのプラグインを適用して、4.84.8164などの数字を5で満たされた4.8618164の星に変える方法を考えていました。/JS/CSS。
これは、すでに利用可能な番号からの星評価のみを表示/表示し、新しい評価提出を受け入れないことに注意してください。
非常に小さくてシンプルな画像を1つと、自動的に生成されたスパン要素を1つだけ使用するソリューションがあります。
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;
}
(ソース: lmanen.fi )
注:doNOT上記の画像へのホットリンク!ファイルを自分のサーバーにコピーして、そこから使用します。
$.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);
});
}
星のサイズを星の半分または4分の1に制限する場合は、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();
});
(ソース: lmanen.fi )
これはおそらくあなたのニーズに合うでしょう。この方法を使用すると、3/4またはその他の星の幅を計算する必要はありません。フロートを与えるだけで星が得られます。
星がどのように表示されるかについての簡単な説明が適切かもしれません。
このスクリプトは、2つのブロックレベルスパン要素を作成します。両方のスパンは、最初に80px * 16pxのサイズと背景画像stars.pngを取得します。スパンはネストされているため、スパンの構造は次のようになります。
<span class="stars">
<span></span>
</span>
外側のスパンは、background-position
の0 -16px
を取得します。これにより、外側のスパンの灰色の星が見えるようになります。外側のスパンの高さは16ピクセルでrepeat-x
であるため、5つの灰色の星のみが表示されます。
一方、内側のスパンにはbackground-position
の0 0
があり、黄色の星のみが表示されます。
もちろん、これは2つの別々の画像ファイルstar_yellow.pngとstar_gray.pngで動作します。しかし、星の高さは固定されているため、それらを1つの画像に簡単に組み合わせることができます。これは CSSスプライトテクニック を利用します。
現在、スパンはネストされているため、自動的に相互にオーバーレイされます。デフォルトの場合、両方のスパンの幅が80pxの場合、黄色の星は灰色の星を完全に覆います。
しかし、内側のスパンの幅を調整すると、黄色の星の幅が小さくなり、灰色の星が現れます。
アクセシビリティに関しては、内部スパン内にフロート数を残し、text-indent: -9999px
で非表示にして、CSSをオフにした人が少なくとも星ではなく浮動小数点数を見るようにする方が賢明でした。
うまくいけば、それは何らかの意味をなした。
さらにコンパクトになり、理解しにくくなりました! 1つのライナーに絞ることもできます。
$.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
を設定するためにJavascriptを使用するためできないであるため)。これを修正するには、上記のソリューションを簡単に調整できます。 :before
および:after
ビットは、DOMの実際の要素になる必要があります(そのためには、JSが必要です)。
後者は読者のための練習問題として残されています。
この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>
星の5つの別々の画像(空、クォーターフル、ハーフフル、スリークォーターフル、フル)だけでなく、4倍した評価の切り捨てられた値またはルーティングされた値に応じて、DOMに画像を挿入するだけではありません(四半期の整数を取得するには)?
たとえば、4.8618164に4を掛けて丸めた値は19で、これは4分の3星です。
あるいは(私のように怠け者の場合)、21から選択した1つの画像(4分の1の増分で0つ星から5つ星)を用意し、前述の値に基づいて単一の画像を選択します。次に、DOMで画像を変更するだけで、1つの計算が行われます(5つの異なる画像を変更しようとするのではなく)。
最終的には、クライアント側のレンダリングラグを回避するために、完全に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 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;
}
ただし、精度が0.5に制限されているJSXと素晴らしいフォントを使用した私の考えは次のとおりです。
<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>
1行目は星全体、2行目は半星(ある場合)