开发者

Populating a five star system in JavaScript with half stars

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜