Apply class when firing mouseenter individually

2

I am trying to make scores with stars and that when passing over each one, a css class is applied. The fact is that it applies to all the stars at once and my intention is that it only applies when you pass the mouse over from beginning to end and that they remain fixed as the score goes up and only while you have the mouse on top.

Here is what I have done.

var estrella = document.getElementsByClassName("star");

function inclinar() {
    for(var i = 0; i < estrella.length; i++) {
        estrella[i].className += " inclinada";
    }
}

function desinclinar() {
    for(var i = 0; i < estrella.length; i++) {
        estrella[i].classList.remove("inclinada");
    }
}

for(var i = 0; i < estrella.length; i++) {
    estrella[i].addEventListener('mouseenter', inclinar);
    estrella[i].addEventListener('mouseleave', desinclinar);
}
.stars ul {
  list-style-type:none;
  padding:0;
}

.stars ul > li.star {
  display:inline-block;
  font-size:2.5em;
  color:#ccc;
}

.stars ul > li.star.inclinada  {
  color:#FFCC31;
  transform: rotate(20deg);
}
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet"/>
<div class="stars text-center">
    <ul id="stars">
      <li class="star" data-value="1">
        <i class="fas fa-star"></i>
      </li>
      <li class="star" data-value="2">
        <i class="fas fa-star"></i>
      </li>
      <li class="star" data-value="3">
        <i class="fas fa-star"></i>
      </li>
      <li class="star" data-value="4">
        <i class="fas fa-star"></i>
      </li>
      <li class="star" data-value="5">
        <i class="fas fa-star"></i>
      </li>
    </ul>
  </div>

Thank you!

    
asked by Britba 26.02.2018 в 14:31
source

3 answers

1

Well, in order not to change your code much, you can obtain the value of the data-value and assign the cycle path to that value. So paint the stars you pass the mouse through

var estrella = document.getElementsByClassName("star");

function inclinar() {
  for (var i = 0; i < this.getAttribute("data-value"); i++) {
    estrella[i].className += " inclinada";
  }
}

function desinclinar() {
  for (var i = 0; i < this.getAttribute("data-value"); i++) {
    estrella[i].classList.remove("inclinada");
  }
}

for (var i = 0; i < estrella.length; i++) {
  estrella[i].addEventListener('mouseenter', inclinar);
  estrella[i].addEventListener('mouseleave', desinclinar);
}
.stars ul {
  list-style-type: none;
  padding: 0;
}

.stars ul>li.star {
  display: inline-block;
  font-size: 2.5em;
  color: #ccc;
}

.stars ul>li.star.inclinada {
  color: #FFCC31;
  transform: rotate(20deg);
}
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet" />
<div class="stars text-center">
  <ul id="stars">
    <li class="star" data-value="1">
      <i class="fas fa-star"></i>
    </li>
    <li class="star" data-value="2">
      <i class="fas fa-star"></i>
    </li>
    <li class="star" data-value="3">
      <i class="fas fa-star"></i>
    </li>
    <li class="star" data-value="4">
      <i class="fas fa-star"></i>
    </li>
    <li class="star" data-value="5">
      <i class="fas fa-star"></i>
    </li>
  </ul>
</div>
    
answered by 26.02.2018 / 15:26
source
0

The problem is that you are going through all the stars and you are applying the inclined class or the same when you remove the mouse.

You can access the target, in this case the li, where you apply the events as follows

var estrella = document.getElementsByClassName("star");

function inclinar(event) {

  var dataValue = event.target.getAttribute('data-value');

  for(var i = 0; i < estrella.length; i++) {
    if(estrella[i].getAttribute('data-value') <= dataValue)
      estrella[i].className += " inclinada";
  }
}

function desinclinar(event) {
  var dataValue = event.target.getAttribute('data-value');

  for(var i = 0; i < estrella.length; i++) {
    if(estrella[i].getAttribute('data-value') > dataValue)
      estrella[i].className = "star";
  }
}

for(var i = 0; i < estrella.length; i++) {
    estrella[i].addEventListener('mouseenter', inclinar);
    estrella[i].addEventListener('mouseleave', desinclinar);
}

the jsfiddle

    
answered by 26.02.2018 в 14:51
0

To do what you want, you do not need JavaScript (at least not for this part), it can be done only with HTML and CSS. The idea would be to use the pseudo-class :hover for when the mouse moves over and the adjacent sibling selector ~ to select the following.

It would be simple changes in your CSS and it would look like this:

  

Notice that I have changed the order of the stars that now go from 5 to 1 instead of 1 to 5.

.stars ul {
  list-style-type: none;
  padding: 0;
  display: inline-block;
  height: auto;
}

.stars ul>li.star {
  display: inline-block;
  font-size: 2.5em;
  color: #ccc;
  float: right;
  transition: all 0.25s;
}

.stars ul>li.star:hover,
.stars ul>li.star:hover~li.star {
  color: #FFCC31;
  transform: rotate(20deg);
}
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet" />
<div class="stars text-center">
  <ul id="stars">
    <li class="star" data-value="5">
      <i class="fas fa-star"></i>
    </li>
    <li class="star" data-value="4">
      <i class="fas fa-star"></i>
    </li>
    <li class="star" data-value="3">
      <i class="fas fa-star"></i>
    </li>
    <li class="star" data-value="2">
      <i class="fas fa-star"></i>
    </li>
    <li class="star" data-value="1">
      <i class="fas fa-star"></i>
    </li>
  </ul>
</div>
    
answered by 26.02.2018 в 16:25