使用jQuery和CSS将数字转换为星级评分显示

时间:2009-12-31 23:56:25

标签: javascript jquery css rating

我一直在关注jquery插件,并想知道如何调整该插件将数字(如4.8618164)变成4.8618164星星填充5.基本上将数字<5变成5星的星星使用jQuery / JS / CSS评级系统。

请注意,这只会显示/显示已有号码的星级,而不接受新的评分提交。

8 个答案:

答案 0 :(得分:253)

这里有一个解决方案,只使用一个非常小而简单的图像和一个自动生成的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;
}

图像

  

alt text
  (来源:ulmanen.fi

注意:执行 NOT 上面图片的热链接!将文件复制到您自己的服务器并从那里使用它。

的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();
});

输出

  

Image from 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-position 0 -16px。这使得外跨度中的灰色星可见。由于外跨度高度为16px且repeat-x,因此仅显示5颗灰星。

另一方面,内跨距有background-position 0 0,只能看到黄色的星星。

这当然适用于两个独立的图像文件,star_yellow.png和star_gray.png。但由于恒星具有固定的高度,我们可以轻松地将它们组合成一个图像。这利用了CSS sprite technique

现在,当跨度嵌套时,它们会自动叠加在一起。在默认情况下,当两个跨度的宽度为80px时,黄色星星会完全遮挡灰色星星。

但是当我们调整内跨的宽度时,黄色恒星的宽度会减小,露出灰色的星星。

可访问性方面,将浮点数保留在内部范围内并用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));
    });
}

答案 1 :(得分:25)

如果您只需支持现代浏览器,则可以使用:

  • 图片;
  • 主要是 static css;
  • 几乎没有jQuery或Javascript;

您只需要将号码转换为class,例如class='stars-score-50'

首先演示&#34;渲染&#34;标记:

&#13;
&#13;
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; }
&#13;
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>
&#13;
&#13;
&#13;

然后使用一小段代码的演示:

&#13;
&#13;
$(function() {
  function addScore(score, $domElement) {
    $("<span class='stars-container'>")
      .addClass("stars-" + score.toString())
      .text("★★★★★")
      .appendTo($domElement);
  }

  addScore(70, $("#fixture"));
});
&#13;
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; }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Generated: <div id="fixture"></div>
&#13;
&#13;
&#13;

此解决方案的最大缺点是:

  1. 您需要元素内的星星生成正确的宽度;
  2. 没有语义标记,例如您希望得分作为元素内的文字;
  3. 它只允许你有多少分数(因为我们不能使用Javascript在伪元素上设置精确的width
  4. 要解决此问题,可以轻松调整上述解决方案。 :before:after位需要成为DOM中的实际元素(因此我们需要一些JS)。

    后者留给读者作为练习。

答案 2 :(得分:19)

试试这个jquery函数

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">

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

<script>
    $.fn.stars = function() {
        return $(this).each(function() {

            var rating = $(this).data("rating");

            var numStars = $(this).data("numStars");

            var fullStar = new Array(Math.floor(rating + 1)).join('<i class="fa fa-star"></i>');

            var halfStar = ((rating%1) !== 0) ? '<i class="fa fa-star-half-empty"></i>': '';

            var noStar = new Array(Math.floor(numStars + 1 - rating)).join('<i class="fa fa-star-o"></i>');

            $(this).html(fullStar + halfStar + noStar);

        });
    }

    $('.stars').stars();

Screenshot

FontAwesome CSS

您可以在http://fontawesome.io/

下载FontAwesome

答案 3 :(得分:7)

为什么不只有五个单独的星形图像(空的,四分之一满,半满,三分之四满和满)然后根据等级的截断或粗略值将图像注入到DOM中到4(为季度获得整数)?

例如,4.8618164乘以4,舍入为19,即四分之三和四分之一星。

或者(如果你像我一样懒惰),只需从21中选择一个图像(0星到5星,以四分之一为增量),并根据上述值选择单个图像。然后它只是一个计算,然后是DOM中的图像更改(而不是尝试更改五个不同的图像)。

答案 4 :(得分:5)

我最终完全没有JS,以避免客户端渲染延迟。为此,我生成如下HTML:

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

为了帮助提高辅助功能,我甚至在title属性中添加原始评级值。

答案 5 :(得分:4)

使用没有原型的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>

答案 6 :(得分:2)

DEMO

您只能使用2张图片。 1颗空白星,1颗恒星。

将填充的图像叠加在另一个的顶部。并将评级数转换为百分比,并将其用作填充图像的宽度。

enter image description here

.containerdiv {
  border: 0;
  float: left;
  position: relative;
  width: 300px;
} 
.cornerimage {
  border: 0;
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
 } 
 img{
   max-width: 300px;
 }

答案 7 :(得分:0)

这是我使用JSX和超棒的字体的经历,但仅限于.5精度,

cli_addr

第一行代表整颗星,第二行代表半颗星(如果有)