实现原理
首先看一下实现的效果图和代码。
function f1(data, star) {
var result = [];
var score = Math.floor(data * 2) / 2;
var hasDecimal = score % 1 !== 0;
var integer = Math.floor(score);
for (var i = 0; i < integer; i++) {
result[i] = "1";
}
if (hasDecimal) {
result.push("2");
}
while (result.length < 5) {
result.push("0");
}
for (var i = 0; i < 5; i++) {
if (result[i] === "1") {
$(star[i]).addClass("on");
} else if (result[i] === "0") {
$(star[i]).addClass("off");
} else if (result[i] === "2") {
$(star[i]).addClass("half");
}
}
}
当我们拿到数据 之后,我们需要显示通过星星的数量来表示评分的效果 ,当然这种效果比生硬的数字看起来确实更加生动。这种效果也比较常见,那么我们要怎么实现呢?
首先我们需要确定实星的个数,这个好说,我们直接对拿到的评分 ,进行取整运算即可,也就是调用Math.floor()方法.
接下来我们需要考虑半星的个数,这个地方我们需要考虑到两种情况:1.十分位大于 5为一颗半星。 2.十分位小于5为空星。考虑到这两种情况是不是很容易联想到对取到的十分位判断。我们可以通过取余运算对得到的小数进行判断。但在此之前需要对我们拿到的数据进行一个化整的过程(Math.floor(data * 2) / 2)。再通过条件判断得到半星的个数
最后我们只需要考虑空星的个数,因为星星总数就是五个,空星的个数等于5减去实星的个数再减去半星的个数。
求出了实星,半星,空星的个数后,可以 用一个数组来表示星星的状态,我用“0”表示的空星,“1”表示的整星,“2”表示的半星,在依次进行判断添加css样式即可。
js实现星星评分代码
<!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>Document</title>
</head>
<style>
li {
height: 20px;
width: 20px;
float: left;
}
.star {
width: 20px;
height: 20px;
float: left;
}
.on {
background-image: url("star24_on@2x.png");
}
.off {
background-image: url("star24_off@2x.png");
}
.half {
background-image: url("star24_half@2x.png");
}
</style>
<body>
<div class="data">3.8</div>
<div class="starts">
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
</div>
<script src="./jquery-3.2.1.js"></script>
<script>
$(function() {
var data = $(".data").html();
var star = $(".star");
f1(data, star);
function f1(data, star) {
var result = [];
var score = Math.floor(data * 2) / 2;
var hasDecimal = score % 1 !== 0;
// var hasDecimal2 = score % 1;
// console.log(hasDecimal2);data为3.8,结果为0.2
//var hasDecimal3 = data % 1;
// console.log(hasDecimal3);data为3.8,结果为0.7999999999999998
var integer = Math.floor(score);
for (var i = 0; i < integer; i++) {
result[i] = "1";
}
/** if (hasDecimal2 > 0.5) {
result.push("2");
}这个判断 方法也可以实现
*/
if (hasDecimal) {
result.push("2");
}
while (result.length < 5) {
result.push("0");
}
for (var i = 0; i < 5; i++) {
if (result[i] === "1") {
$(star[i]).addClass("on");
} else if (result[i] === "0") {
$(star[i]).addClass("off");
} else if (result[i] === "2") {
$(star[i]).addClass("half");
}
}
}
})
</script>
</body>
</html>
Vue实现星星评分代码
星星组件代码:
<template>
<div class="star" :class="starType">
<span v-for="(itemClass, index) in itemClasses" :class="itemClass" class="star-item"></span>
</div>
</template>
<script type="text/ecmascript-6">
const LENGTH = 5;
const CLS_ON = 'on';
const CLS_HALF = 'half';
const CLS_OFF = 'off';
export default{
props: {
size: {
type: Number
},
score: {
type: Number
}
},
data() {
return {
}
},
computed: {
starType() {
return 'star-' + this.size;
},
itemClasses() {
let result = [];
let score = Math.floor(this.score * 2) / 2;
let hasDecimal = score % 1 !== 0;
let integer = Math.floor(score);
for (let i = 0; i < integer; i++) {
result.push(CLS_ON);
}
if (hasDecimal) {
result.push(CLS_HALF);
}
while(result.length < LENGTH){
result.push(CLS_OFF);
}
return result;
}
},
methods: {}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "../../common/scss/mixins";
.star {
font-size: 0;
.star-item {
display: inline-block;
background-repeat: no-repeat;
}
&.star-48 {
.star-item {
width: 20px;
height: 20px;
margin-right: 22px;
background-size: 20px 20px;
&:last-child {
margin-right: 0;
}
&.on {
@include bg-image('star48_on');
}
&.half {
@include bg-image('star48_half');
}
&.off {
@include bg-image('star48_off');
}
}
}
&.star-36 {
.star-item {
width: 15px;
height: 15px;
margin-right: 6px;
background-size: 15px 15px;
&:last-child {
margin-right: 0;
}
&.on {
@include bg-image('star36_on');
}
&.half {
@include bg-image('star36_half');
}
&.off {
@include bg-image('star36_off');
}
}
}
&.star-24 {
.star-item {
width: 10px;
height: 10px;
margin-right: 3px;
background-size: 10px 10px;
&:last-child {
margin-right: 0;
}
&.on {
@include bg-image('star24_on');
}
&.half {
@include bg-image('star24_half');
}
&.off {
@include bg-image('star24_off');
}
}
}
}
</style>
这里面的starType是在移动端确定星星图片大小。关于数据的传送这里就不说了,大家只需要理解实现的方法。
<star :size="36" :score="seller.score"></star>
小程序实现星星评分代码
util.js代码如下
function convertToStarsArray(data) {
var result = [];
var score = Math.floor(data * 2) / 2;
var hasDecimal = score % 1 !== 0;
var integer = Math.floor(score);
for (var i = 0; i < integer; i++) {
result[i] = "1";
}
if (hasDecimal) {
result.push("2");
}
while (result.length < 5) {
result.push("0");
}
return result;
}
组件代码
<block wx:for="{{stars}}" wx:for-item="i">
<image wx:if="{{i===1}}" src="/images/icon/star.png"></image>
<image wx:elif="{{i === 2}}"> 2src="/images/icon/half-star.png"></image>
<image wx:else src="/images/icon/none-star.png"></image>
</block>
在这里还是想说一下,我虽然给了三段代码,但原理都是一样的。唯一的差别就是不同的环境下实现的方式稍微有点不一样。