如何通过淘汰赛实现 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>

【问题讨论】:

您需要独特的idforname 用于两组评级,如果您需要提供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 星级评分?

Django 星级评分系统 AJAX 和 JavaScript

js实现星级评分之方法一

css facetwp不显示和悬停星级评分

Vue实现一个星级评分组件

Android中点击按钮获取星级评分条的评分