如何通过淘汰赛实现 CSS 星级评分
Posted
技术标签:
【中文标题】如何通过淘汰赛实现 CSS 星级评分【英文标题】:how to implement a css star rating with knockout 【发布时间】:2020-04-03 11:56:04 【问题描述】:有一个我想要实施的星级评定,它的工作范围是可以点击星星,我遇到的问题是当我显示多组星星时。发生的事情是点击了哪一组星星,它会影响另一组,只有改变点击的数量。如果我没有很好地解释,假设我有 3 颗星,我去第一组并给它一个 5 星评级,它保持这个值(都很好),但是如果去下一组星并给这个值说 2,这第二组将保持 2 星的值,但是上面的设置设置为无。就像检查的事件对于每个集合并不是唯一的并且重置另一个集合。我为此使用 bootstrap 和 Knockout js,我试图提供一个唯一的 ID,希望可以解决它,但没有运气。任何人都可以帮助解决这个问题?
下面的代码,我已经跳过了一些创建我的可观察数组的淘汰赛代码,我有这个工作,因为我为我的每个 feedbackToBeLeft 数组获得了一组星
<style>
.star-rating
font-size: 0;
.star-rating__wrap
display: inline-block;
font-size: 16px;
.star-rating__wrap:after
content: "";
display: table;
clear: both;
.star-rating__ico
float: right;
padding-left: 2px;
cursor: pointer;
color: #9933cc;
.star-rating__ico:last-child
padding-left: 0;
.star-rating__input
display: none;
.star-rating__ico:hover:before,
.star-rating__ico:hover ~ .star-rating__ico:before,
.star-rating__input:checked ~ .star-rating__ico:before
content: "\f005";
<div data-bind="foreach: feedbackToBeLeft"><table style="background-color:transparent;border:none;">
<tr>
<td style="width:100px;">
Rating
</td>
<td>
<div class="star-rating" data-bind="attr: id: 'star_' + bookingGuid ">
<div class="star-rating__wrap" data-bind="attr: id: 'wrap_' + bookingGuid ">
<input class="star-rating__input" data-bind="attr: id: 'star5_' + bookingGuid " type="radio" name="rating" value="5">
<label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: for: 'star5_' + bookingGuid " title="Amazing"></label>
<input class="star-rating__input" data-bind="attr: id: 'star4_' + bookingGuid " type="radio" name="rating" value="4">
<label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: for: 'star4_' + bookingGuid " title="Good"></label>
<input class="star-rating__input" data-bind="attr: id: 'star3_' + bookingGuid " type="radio" name="rating" value="3">
<label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: for: 'star3_' + bookingGuid " title="Ok"></label>
<input class="star-rating__input" data-bind="attr: id: 'star2_' + bookingGuid " type="radio" name="rating" value="2">
<label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: for: 'star2_' + bookingGuid " title="Not good"></label>
<input class="star-rating__input" data-bind="attr: id: 'star1_' + bookingGuid " type="radio" name="rating" value="1">
<label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: for: 'star1_' + bookingGuid " title="Bad"></label>
</div>
</div>
</td>
</tr>
</table></div>
【问题讨论】:
您需要独特的id
和for
和name
用于两组评级,如果您需要提供sn-p
在你上面的例子中,我没有看到一个独特的name
用于设置 2 个评级星
【参考方案1】:
这就是我会如何接近你想要做的事情。
var ratings = [
name: 'Bad',
value: 1
,
name: 'Not Good',
value: 2
,
name: 'Ok',
value: 3
,
name: 'Good',
value: 4
,
name: 'Amazing',
value: 5
,
];
var data = [
bookingGuid: '11111111-1111-1111-1111-111111111111',
bookingName: 'Room 1',
ratingValue: 4
,
bookingGuid: '22222222-2222-2222-2222-222222222222',
bookingName: 'Room 2',
ratingValue: 2
];
function StarRatingVm(id, title, value)
var self = this;
self.id = id;
self.value = value;
self.title = title;
self.groupName = ko.pureComputed(function()
return 'star_' + self.id;
);
self.name = ko.pureComputed(function()
return 'star' + self.value + '_' + self.id;
);
function Vm()
var self = this;
var mappedData = data.map(function(item)
item.availableRatings = createRatings(item.bookingGuid, ratings);
item.selectedValue = ko.observableArray();
return item;
)
self.feedbackToBeLeft = ko.observableArray(mappedData);
function createRatings(id, ratings)
return ratings.map(function(item)
return new StarRatingVm(id, item.name, item.value);
);
var vm = new Vm();
window.vm = vm;
ko.applyBindings(vm);
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: data: feedbackToBeLeft, as: 'feedback'">
<table style="background-color:transparent;border:none;">
<tr>
<td style="width:100px;">
Rating <span data-bind="text: feedback.bookingName"></span>
</td>
<td>
<div class="star-rating" data-bind="attr: id: 'star_' + bookingGuid ">
<div class="star-rating__wrap" data-bind="attr: id: 'wrap_' + bookingGuid , foreach: data: availableRatings, as : 'rating'">
<input class="star-rating__input" data-bind="checkedValue: rating, checked: feedback.selectedValue, attr: id: rating.name, name: rating.groupName, title: rating.title " type="radio">
<label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: for: rating.name, title: rating.title "></label>
</div>
</div>
</td>
</tr>
</table>
</div>
<br/>
<ul data-bind="foreach: feedbackToBeLeft">
<li><span data-bind="text: bookingName"></span> Rating: <span data-bind="text: selectedValue().value"></span> stars</li>
</ul>
<pre data-bind="text: ko.toJSON(vm)"></pre>
【讨论】:
很好的例子非常感谢,我真的需要字体很棒的星星,我的例子与css和前后属性有关。我不知道如何正确操作这些,只是要从整个该死的事情重新开始:(以上是关于如何通过淘汰赛实现 CSS 星级评分的主要内容,如果未能解决你的问题,请参考以下文章
如何使用带有 Django 模板标签的 amp CSS 星级评分?