前言
小编最近在做星级评价实现半颗星评价的功能,得到这个需求,便开始了探索之旅,一开始自己登陆淘宝网查看评价效果,发现没有半颗星的效果,并且在网上查找半颗星的相关博客或网页,没有结果,便向项目组长提出,这个需求没有必要实现吧,并拿出了淘宝网的例子,结果组长告诉我这是体验用户提出来的,并且她自己已经在网上找到了相应的demo效果。
最后我被组长成功说服了,打算去试一试,便搜索关键字“ionic实现半颗星评价”,果然找到了组长所演示的demo,看来并不是不能做,只是自己没有找到真正的解决之道。看来有了小瓶颈之后,找组长交流一下也是会有突破的,^_^。
demo效果
一、demo地址
https://blog.csdn.net/qq_30433815/article/details/78486484
二、demo效果
我才用的是第二种效果,点击实现半颗星。
个人实现过程
一、CSS样式
主要是设计星星图片的样式,两张图片使用div包装起来,一张空星星图片的overflow的属性为hidden。
overflow 属性规定当内容溢出元素框时发生的事情。 hidden 内容会被修剪,并且其余内容是不可见的 |
/*********************************************星级评价半颗星***********************************************************/
.stars-off {
margin-top: 10px;
background-size: 101px;
width: 100px;
height: 20px;
overflow: hidden;
text-align: left;
}
.stars-on {
background-size: 101px;
height: 300%;
}
/*********************************************星级评价半颗星***********************************************************/
二、HTML元素设计
其中在ionic中使用了[ngStyle]属性绑定,来获取ts文件中的变量的值。
<ion-list *ngFor="let level of secondLevel;let j=index" style="margin-top: 5px;">
<ion-list-header style="margin-bottom: 2px;">
<p style="font-size: 18px;color:black;"> {{level.name}}</p>
</ion-list-header>
<div *ngFor="let item of level.templetAppraiseEntityList; let i=index">
<ion-item-sliding>
<ion-item>
<div class="star-div">
<div>{{item.name}} ({{item.weight}}分)</div>
<span (click)="chooseStar($event,id,detailId,item)">
<!-- 星级评价关键部分 -->
<div class="stars-off" style="background-image: url(assets/imgs/star-off.png);background-repeat: no-repeat">
<div class="stars-on" [ngStyle]="starts[item.index]"></div>
</div>
<!-- 星级评价关键部分 -->
</span>
<span class="scoreSpan">{{scoreItem[item.index]}}</span>
<span #id style="display: none">{{item.id}}</span>
<span #detailId style="display: none">{{item.detailId}}</span>
</div>
</ion-item>
</ion-item-sliding>
</div>
</ion-list>
三、TS逻辑判断
//星级评价的星星对象,属性如下图片地址以及显示的width 假设有五条评价记录
starts = [
{ 'width': '0%', 'background-image': 'url(assets/imgs/star-on.png)', 'background-repeat': 'no-repeat' },
{ 'width': '0%', 'background-image': 'url(assets/imgs/star-on.png)', 'background-repeat': 'no-repeat' },
{ 'width': '0%', 'background-image': 'url(assets/imgs/star-on.png)', 'background-repeat': 'no-repeat' },
{ 'width': '0%', 'background-image': 'url(assets/imgs/star-on.png)', 'background-repeat': 'no-repeat' },
{ 'width': '0%', 'background-image': 'url(assets/imgs/star-on.png)', 'background-repeat': 'no-repeat' }
];
starW = 0; //显示星星被填充形状
star = 5; //五颗星
index = 0;
//点击星星触发此事件
chooseStar(e, id, detailId, item) {
var offset = $(e.target).offset();
var x = e.pageX;
var left = offset.left;
this.starW = Math.ceil((x - left) / 10) * 10;
if (this.starW % 2 != 0) {
this.starW += 10;
}
this.star = this.starW / 20
this.starts[item.index].width = this.starW.toString() + '%';
//判断点了几颗星星,通过星星的权重算分
this.integral = item.oneStarIntegral * this.star;
// 实例化detailList用来接收每一条二级模板的评价内容
let detailList = new scoreDetailModel();
//将每一条的分数和对应的id赋值给detailList
detailList.appraiseId = id.innerText;
detailList.integral = this.integral;
detailList.detailId = detailId.innerText;
// 把list赋值给detailModel
this.detailArray[item.index] = detailList;
// 获取所有二级的分数,用于计算总分
this.scoreItem[item.index] = this.integral;
var sum = 0;
// 循环计算总分
for (let i = 0; i < this.scoreItem.length; i++) {
sum = sum + this.scoreItem[i];
}
//总分
this.sumIntegral = sum;
// item.score.star = star;
item.score.star = this.star;
}
小结
实现这个功能的过程中,小编遇到了两个小问题:(1)HTML文件中的 style属性不能获取ts中的变量值,便改用了[ngStyle];(2)星级评价的图片的路径问题,在本地与发布后在服务器上识别的路径不一样,图片路径写在css中会不识别,所以将它写在HTML元素或者ts中的变量中(此变量是提供给HTML元素使用的),这样的话直接写图片所在的绝对路径即可,如assets/imgs/star-on.png。
感谢您的访问!