C. Yee
C. Yee

Reputation: 197

Same image shown multiple times. Change only one at a time using JQuery

I have an image of a gray star or blue star shown multiple times on the page. When I click on the gray star, it should change to blue. And when I click on the blue star, it should change to gray. Right now, when I click on one star, it changes all of them. How do I only change one image at a time?

This is in my root.html.erb

<img class="star-pic" src="/assets/star-gray.png">

This is in my javascript/application.js

$(document).ready(function(){

  function changeStar(){
    if($(".star-pic").attr("src") == "/assets/star-gray.png"){
      $(".star-pic").attr("src", "/assets/star-blue.png")
    }
    else{
      $(".star-pic").attr("src", "/assets/star-gray.png")
    }
  }

  $(".star-pic").on("click", changeStar)

})

Any advice would be greatly appreciated. Thank you.

Upvotes: 1

Views: 849

Answers (4)

Scott Marcus
Scott Marcus

Reputation: 65806

You are setting up your click event such that all .star-pic elements have their style modified when any are clicked because of this:

$(".star-pic").attr("src", "/assets/star-blue.png")

This changes the src attribute for all members of the JQuery wrapped set.

You only want to modify the one that was clicked so you should be writing:

$(this).attr("src", "/assets/star-blue.png")

to only affect the one that was clicked.

But, beyond that, your code can be dramatically reduced and the solution hugely simplified if you get rid of the img elements completely and just use div (or span) elements that have their background-image set via membership in a CSS class. Then, all you have to do it toggle that class membership.

$(function(){
  function changeStar(){
    // Use $(this) to get a reference to just the element being clicked as a JQuery object
    // Simply toggle the use of the greyStar class to toggle the image shown
    $(this).toggleClass("greyStar");
  }

  $(".star-pic").on("click", changeStar)
});
.star-pic {
  width:50px;
  height:50px;
  background-size:cover;
  /* All elements default to showing a blue star */
  background-image:url("https://upload.wikimedia.org/wikipedia/commons/9/98/Human-emblem-star-blue-128.png");
  display:inline-block;
}

/* But some elements are coded in the HTML to override blue and show grey from the start */
.greyStar {
  background-image:url("http://www.dyson.com/airtreatment/humidifiers/am10/am10-white-silver/medialibrary/Reviews/Grey-star.ashx");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="star-pic greyStar"></span>
<span class="star-pic"></span>
<span class="star-pic greyStar"></span>
<span class="star-pic"></span>
<span class="star-pic greyStar"></span>
<span class="star-pic"></span>

Upvotes: 1

Sid24
Sid24

Reputation: 334

Inside your function changeStar() you are selecting all the images when any image is clicked and changing all of them as a result. Using $(this) selects the element that was clicked and changes it only.

$(document).ready(function() {
  function changeStar() {
    if ($(this).attr("src") == "/assets/star-gray.png") {
      $(this).attr("src", "/assets/star-blue.png")
    } else {
      $(this).attr("src", "/assets/star-gray.png")
    }
  }

  $(".star-pic").on("click", changeStar)
})

Upvotes: 2

Sachin Kumar
Sachin Kumar

Reputation: 3240

You can use the following code.

<!DOCTYPE html>
<html>
<head>
  <script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>

</head>
<body>
<img class="star-pic" src="/assets/star-gray.png">
<img class="star-pic" src="/assets/star-gray.png">
<img class="star-pic" src="/assets/star-gray.png">



<script>
$(document).ready(function(){
  var clickedShape = $(this);
  function changeStar(){
    if($(this).attr("src") == "/assets/star-gray.png"){
      $(this).attr("src", "/assets/star-blue.png")
    }
    else{
      $(this).attr("src", "/assets/star-gray.png")
    }
  }

  $(".star-pic").on("click", changeStar)

})

</script>

</body>
</html>

Upvotes: 0

dermitzos
dermitzos

Reputation: 1

You should could assign a click function at the star and change the corresponding star using 'this'

$(".star-pic").click(function (){
  if($(this).attr("src") === "/assets/star-gray.png"){
    $(this).attr("src", "/assets/star-blue.png")
  }else{
    $(this).attr("src", "/assets/star-gray.png")
  }
}

Upvotes: 0

Related Questions