Carter
Carter

Reputation: 123

Loop an array with an "click" function

I'm trying to have it so that whenever the button is clicked it will then change to the next background image.

var images = [
  "http://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-2-Large.jpg",
  "http://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-6-Large.jpg",
  "http://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-1-Large.jpg"
]

for (var i = 0; i < images.length; i++) {
  $("#changeBg").click(function() {
    $("body").css("background-image", "images.length[i]");
  } 

Upvotes: 1

Views: 261

Answers (2)

Animesh Kumar
Animesh Kumar

Reputation: 237

Rory explained it perfectly and also mentioned what's wrong with your code. The main issue was that you were unable to keep the trace of how many times the button was clicked.

And Rory gave a pretty good solution using the data attribute.

However, there's one more (or may be many more) way to solve the problem. Using Closures.

var images = [
  "http://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-2-Large.jpg",
  "http://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-6-Large.jpg",
  "http://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-1-Large.jpg"
];

(function(){
  var count = 0;
  $("#changeBg").click(function(){
    var imgNo = count % images.length;
    document.body.style.backgroundImage = "url( " + images[imgNo] + ")";
    count++;
  });
})();

In this case, the event handler function has closure over the count variable. For details on closure, I would suggest you to go through this page -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Upvotes: 1

Rory McCrossan
Rory McCrossan

Reputation: 337560

There's a few issues in your code. Firstly you need to attach a single event handler and progress through the elements of array on each successive click event. Attaching the event handlers in a loop will just create conflicts, as you're instantly trying to do the same action multiple times.

Within the single event handler you can use a variable to keep track of your current position in the array and increment it on each click. A data attribute is ideal for this.

Secondly, you need to actually use the value within the array element, not wrap that reference in quotes. You also need to access the array by index, not the length property specifically.

Lastly you need to wrap the URL of the image in the CSS attribute in url("...").

var images = [
  "https://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-2-Large.jpg",
  "https://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-6-Large.jpg",
  "https://helenspeyer.co.uk/wp-content/gallery/the-end-of-the-f-ing-world/The-end-of-the-f...ing-world-1-Large.jpg"
]

$("#changeBg").click(function() {
  var counter = $(this).data('counter') || 0;
  $("body").css("background-image", 'url("' + images[counter % images.length] + '")');
  $(this).data('counter', ++counter);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="changeBg">Change background</button>

Upvotes: 1

Related Questions