I'm trying to figure out how to write a javascript function that takes an element + a score and uses jQuery addClass
and removeClass
to display the correct star rating (rounded to the nearest half star) but having problems... When I was using a "whole star" system I used something this system:
function() {
$(this).prevAll().andSelf().addClass('active');
$(this).nextAll().removeClass('active');
}
Which no longer works for a half-star system. Does anyone have any advice? Here is the code I'm using now:
function populateStars(stars, score) {
// Stars refers to the <ul> container with <li> stars inside (see later code).
// This function should use stars (container) and score (rating between 1-5) to display stars
}
This is an example of the elements that the "stars" var refers to:
<ul class="big-stars">
<li class="star-1 full">开发者_如何学JAVA;1</li>
<li class="star-2 full">2</li>
<li class="star-3 half">3</li>
<li class="star-4">4</li>
<li class="star-5">5</li>
</ul>
And the CSS that controls whether the star is full, empty or half-full.
.big-stars li {
text-indent: -9999px;
width: 49px;
height: 46px;
background: url('../images/big_star_empty.png');
}
.big-stars .full {
background: url('../images/big_star_full.png');
}
.big-stars .half {
background: url('../images/big_star_half.png');
}
function populateStars (stars, score)
{
// Get the number of whole stars
var iWholeStars = Math.floor(score);
// Do we want a half star?
var blnHalfStar = (iWholeStars < score);
// Show the stars
for (var iStar = 1; iStar <= iWholeStars; iStar++)
{
$('li.star-' + iStar, stars).addClass('full');
}
// And the half star
if (blnHalfStar)
{
$('.star-' + iStar, stars).addClass('half');
}
}
populateStars($('.big-stars'), 3.5)
Obviously this can be condensed by just moving the variable declarations straight to where they're being used.
Edit: JSFiddle link :) http://jsfiddle.net/G8kwb/
Edit 2: JSFiddle link with rounding to nearest half number: http://jsfiddle.net/G8kwb/8/
Here's another possibility, using some jQuery lt and eq selectors:
function populateStars (stars, score)
{
//round to nearest half
score = Math.round(score * 2) / 2;
var scoreParts = score.toString().split('.');
$(stars + ' li:lt('+ scoreParts[0]+')').addClass('full');
if(scoreParts[1])
{
$(stars + ' li:eq('+ scoreParts[0] +')').addClass('half');
}
}
populateStars('.big-stars', 3.5);
You need to pass the parent class rather than the actual object to the method, but it's an interesting option for you.
Edit: here's an updated fiddle with rounding: jsFiddle, thanks to Joe for the initial version!
Also, I found the rounding logic in this interesting related question - Turn a number into star rating.
Here is what I came up with, should it help anyone (using fontawesome for the stars, but one could substitute styled elements:
function getRankStars(rank){
// Round down to get whole stars:
var wStars = Math.floor(rank);
// Check if whole is less than rank.
// If less than rank, a half star is needed:
var halfStars = (wStars < rank);
var output="";
//Loop through five stars:
for(let i=1;i<=5;i++){
//Less than or equal to stars, display a solid star:
if(i<=wStars){
output+="</i><i class='fas fa-star' style='color:#fbcc05'></i>";
//If interation is after a whole star and a half star is needed, display half star:
}else if( i==wStars+1 && halfStars==true ){
output+="<i class='fas fa-star-half-alt' style='color:#fbcc05'></i>";
//Otherwise, display a gray empty star:
}else{
output+="<i class='far fa-star' style='color:#bfbfbf'></i>";
}
}
return output;
}
精彩评论