最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Change star rating on hover - Stack Overflow

programmeradmin4浏览0评论

I use this code to display stars:

<ul class="rating">
<li>
<span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio">
<label class="full" for="Degelijkheid-1-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio">
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio">
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio">
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio">
<label class="full" for="Degelijkheid-5-5"></label>
</span>
</li>
</ul>

Dynamic code:

         <ul class="rating">
            <?php foreach ($this->getRatings() as $_rating): ?>
                <li>
                    <span class="rowlabel"><?php echo $this->escapeHtml($_rating->getRatingCode()) ?></span>
                    <span class="ratingSelector">
                <?php foreach ($_rating->getOptions() as $_option): ?>
                    <input type="radio" name="ratings[<?php echo $_rating->getId() ?>]" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>-<?php echo $_option->getValue() ?>-5" value="<?php echo $_option->getId() ?>" class="radio" /><label class="full" for="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>-<?php echo $_option->getValue() ?>-5"></label>
                <?php endforeach; ?>
                </span>
                </li>
            <?php endforeach; ?>
        </ul>

But hovering and selecting currently works from right to left, but I want to change this from left to right.

Code is loaded dynamically, so I can not change the sort and put value 5 first. This dynamic code is loaded 5 times, for 5 different ratings.

How can I change this? Or what code of JQuery do I need?

JSFiddle: /

I use this code to display stars:

<ul class="rating">
<li>
<span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio">
<label class="full" for="Degelijkheid-1-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio">
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio">
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio">
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio">
<label class="full" for="Degelijkheid-5-5"></label>
</span>
</li>
</ul>

Dynamic code:

         <ul class="rating">
            <?php foreach ($this->getRatings() as $_rating): ?>
                <li>
                    <span class="rowlabel"><?php echo $this->escapeHtml($_rating->getRatingCode()) ?></span>
                    <span class="ratingSelector">
                <?php foreach ($_rating->getOptions() as $_option): ?>
                    <input type="radio" name="ratings[<?php echo $_rating->getId() ?>]" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>-<?php echo $_option->getValue() ?>-5" value="<?php echo $_option->getId() ?>" class="radio" /><label class="full" for="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>-<?php echo $_option->getValue() ?>-5"></label>
                <?php endforeach; ?>
                </span>
                </li>
            <?php endforeach; ?>
        </ul>

But hovering and selecting currently works from right to left, but I want to change this from left to right.

Code is loaded dynamically, so I can not change the sort and put value 5 first. This dynamic code is loaded 5 times, for 5 different ratings.

How can I change this? Or what code of JQuery do I need?

JSFiddle: https://jsfiddle/9nn14beq/

Share Improve this question edited Jun 1, 2015 at 11:02 JGeer asked Jun 1, 2015 at 8:27 JGeerJGeer 1,8521 gold badge36 silver badges78 bronze badges 8
  • I don't think this is possible with only css. because css rule is applied for next sibling not for previous. You should also use JQuery. – ketan Commented Jun 1, 2015 at 8:34
  • 1 See my star rating system in CSS - codepen.io/vsync/pen/qvhtf – vsync Commented Jun 1, 2015 at 8:37
  • @vsync What exactly are you doing different than my code? – JGeer Commented Jun 1, 2015 at 8:42
  • @Jelle - well I saw you are trying to make a star rating system and since I wrote a good one some years ago, I thought it would be nice to share it, so you could use it. Read the source code and learn how it was done – vsync Commented Jun 1, 2015 at 9:19
  • @ketan Yes, it is posible with CSS only. See my answer – vals Commented Jun 1, 2015 at 9:56
 |  Show 3 more ments

4 Answers 4

Reset to default 8

This can almost work with pure CSS. It does need one line of JavaScript to set the initial value though:

document.getElementById('Degelijkheid-1-5').checked = true;
.rating input {
    display: none;
}
.rating label:before {
    margin: 5px;
    font-size: 1.25em;
    font-family: FontAwesome;
    display: inline-block;
    content:"\f005";
}
li {
    list-style:none;
}

.ratingSelector input + label {
    color: #FFD700;
}
.ratingSelector input:checked ~ input:not(:checked) ~ label {
    color: #ddd;
}
.ratingSelector input:checked ~ input:not(:checked) + label:hover ~ label {
    color: #ddd;
}
.ratingSelector:hover input + label,
.ratingSelector:hover input:checked + label {
    color: #FFED85;
}
.ratingSelector:hover input:checked ~ input:not(:checked) ~ label:hover,
.ratingSelector:hover input:checked ~ input:not(:checked) + label {
    color: #FFD700;
}
.ratingSelector:hover input:checked ~ input:not(:checked) ~ label:hover ~ label {
    color: #ddd !important;
}
.ratingSelector input + label:hover ~ label {
    color: #ddd !important;
}
<ul class="rating">
    <li> <span class="ratingSelector">
    <input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio"/>
<label class="full" for="Degelijkheid-1-5"></label>
    <input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio"/>
<label class="full" for="Degelijkheid-2-5"></label>
    <input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio"/>
<label class="full" for="Degelijkheid-3-5"></label>
    <input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio"/>
<label class="full" for="Degelijkheid-4-5"></label>
    <input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio"/>
<label class="full" for="Degelijkheid-5-5"></label>
    </span>
    </li>
</ul>

EDIT

To use JS (to re-order the items):

var objGroup = document.getElementsByClassName('ratingSelector');
for (var i = 0; i < objGroup.length; i++) {
  var objRadio = [].slice.call(objGroup[i].getElementsByClassName('full')); // Create an array of items
  for (var j = objRadio.length; j--;) { // Loop through the array backwards
    var checkbox = document.getElementById(objRadio[j].getAttribute('for'));
    objGroup[i].appendChild(checkbox);
    objGroup[i].appendChild(objRadio[j]);
  }
}
.rating {
  direction: rtl;
  text-align: left;
}
.rating input {
  display: none;
}
.rating label:before {
  margin: 5px;
  font-size: 1.25em;
  font-family: FontAwesome;
  display: inline-block;
  content: "\f005";
}
li {
  list-style: none;
}
.rating label {
  color: #ddd;
}
/***** CSS to Highlight Stars on Hover *****/

.ratingSelector input:checked ~ label,
/* show gold star when clicked */

.ratingSelector label:hover,
/* hover current star */

.ratingSelector label:hover ~ label {
  color: #FFD700;
}
/* hover previous stars in list */

.ratingSelector input:checked + label:hover,
/* hover current star when changing rating */

.ratingSelector input:checked ~ label:hover,
.ratingSelector label:hover ~ input:checked ~ label,
/* lighten current selection */

.ratingSelector input:checked ~ label:hover ~ label {
  color: #FFED85;
}
<ul class="rating">
  <li> <span class="ratingSelector">
    <input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio"/>
<label class="full" for="Degelijkheid-1-5"></label>
    <input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio"/>
<label class="full" for="Degelijkheid-2-5"></label>
    <input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio"/>
<label class="full" for="Degelijkheid-3-5"></label>
    <input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio"/>
<label class="full" for="Degelijkheid-4-5"></label>
    <input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio"/>
<label class="full" for="Degelijkheid-5-5"></label>
    </span>
  </li>
  <li> <span class="ratingSelector">
    <input type="radio" name="ratings[2]" id="Design-1-5" value="1" class="radio"/>
<label class="full" for="Design-1-5"></label>
    <input type="radio" name="ratings[2]" id="Design-2-5" value="2" class="radio"/>
<label class="full" for="Design-2-5"></label>
    <input type="radio" name="ratings[2]" id="Design-3-5" value="3" class="radio"/>
<label class="full" for="Design-3-5"></label>
    <input type="radio" name="ratings[2]" id="Design-4-5" value="4" class="radio"/>
<label class="full" for="Design-4-5"></label>
    <input type="radio" name="ratings[2]" id="Design-5-5" value="5" class="radio"/>
<label class="full" for="Design-5-5"></label>
    </span>
  </li>
  <li> <span class="ratingSelector">
    <input type="radio" name="ratings[3]" id="Gebruiksgemak-1-5" value="1" class="radio"/>
<label class="full" for="Gebruiksgemak-1-5"></label>
    <input type="radio" name="ratings[3]" id="Gebruiksgemak-2-5" value="2" class="radio"/>
<label class="full" for="Gebruiksgemak-2-5"></label>
    <input type="radio" name="ratings[3]" id="Gebruiksgemak-3-5" value="3" class="radio"/>
<label class="full" for="Gebruiksgemak-3-5"></label>
    <input type="radio" name="ratings[3]" id="Gebruiksgemak-4-5" value="4" class="radio"/>
<label class="full" for="Gebruiksgemak-4-5"></label>
    <input type="radio" name="ratings[3]" id="Gebruiksgemak-5-5" value="5" class="radio"/>
<label class="full" for="Gebruiksgemak-5-5"></label>
    </span>
  </li>
</ul>

You expected thing is possible with only css. Because css rule is applied for next sibling not for previous. You should also use JQuery.

But you can do it using following trick using css:

.rating input { display: none; } 
.rating label:before { 
  margin: 5px;
  font-size: 1.25em;
  font-family: FontAwesome;
  display: inline-block;
  content: "\f005";
}

li {list-style:none;
direction:rtl;
text-align: left;}

.rating label { 
  color: #ddd;
}

/***** CSS to Highlight Stars on Hover *****/

.rating input:checked ~ label, /* show gold star when clicked */
.rating:not(:checked) label:hover, /* hover current star */
.rating:not(:checked) label:hover ~ label { color: #FFD700;  } /* hover previous stars in list */

.rating input:checked + label:hover, /* hover current star when changing rating */
.rating input:checked ~ label:hover,
.rating label:hover ~ input:checked ~ label, /* lighten current selection */
.rating input:checked ~ label:hover ~ label { color: #FFED85;  } 
<ul class="rating">
<li>
<span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio">
<label class="full" for="Degelijkheid-5-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio">
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio">
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio">
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio">
<label class="full" for="Degelijkheid-1-5"></label>
</span>
</li>
</ul>

As stated in previous answers, CSS selectors work only in the netural order of the DOM. (Even though this can change some time in the future).

So, if you can not change your DOM, you need to reverse your CSS logic:

Change all the elements on hover of the container. And then use the sibling selector to change the elements to the right of the hovered item

.rating input { display: none; } 
.rating label:before { 
  margin: 5px;
  font-size: 1.25em;
  font-family: FontAwesome;
  display: inline-block;
  content: "\f005";
}

li {list-style:none; }

/***** CSS to Highlight Stars on Hover *****/

.rating label {color: grey;}
label:hover { color: red;  }
.ratingSelector:hover .full {color: red; }
.full:hover ~ .full { color: grey !important;  } 
<ul class="rating">
<li>
<span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio">
<label class="full" for="Degelijkheid-1-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio">
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio">
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio">
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio">
<label class="full" for="Degelijkheid-5-5"></label>
</span>
</li>
</ul>

Just add the below CSS code to make it from left to right:

.ratingSelector {
    max-width: 145px;
    display: inline-block;
}
.rating label {
    float: right;
}
发布评论

评论列表(0)

  1. 暂无评论