A Y
A Y

Reputation: 11

jQuery / Javascript - loop

I want to make it so when I click somewhere in my website, the background changes. I have three backgrounds, and I want to make a loop of them.

$(document).ready(function() {
 $('body').click((function(){
  return function()
  {
   if (counter == null) {
    var counter = 1;
   }
   if(counter == 3) {
     $(this).css("background-image","url(3.jpg)");
     $(this).css("background-position","10% 35%");
     var counter = null;
   }
   if(counter == 2) {
     $(this).css("background-image","url(2.jpg)");
     $(this).css("background-position","10% 35%");
     var counter = 3;
   }
   if(counter == 1) {
     $(this).css("background-image","url(1.jpg)");
     $(this).css("background-position","40% 35%");
     var counter = 2;
   }


  }
 })());

});

Why doesn't this work?

Upvotes: 0

Views: 191

Answers (6)

Šime Vidas
Šime Vidas

Reputation: 185883

$(document).ready(function () {

    function changeBgImage() {
        var imgs = [
            ["1.jpg", "10% 35%"],
            ["2.jpg", "10% 35%"],
            ["3.jpg", "40% 35%"]
        ];
        var counter = 0;

        return function() {
            $(this).css({
                "backgroundImage": "url(" + imgs[counter][0] + ")",
                "backgroundPosition": imgs[counter][1]
            });
            counter += 1;
            if (counter === imgs.length) { counter = 0; }
        };      
    }

    $('body').click(changeBgImage());

});

Update:

OK, so here we have another solution. It is basically Nick's answer but without redundancy.

$(function () {    
    var imgs = [["1.jpg", "10% 35%"], ["2.jpg", "10% 35%"], ["3.jpg", "40% 35%"]];
    var i = 0;    
    $("body").click(function () {
        $(this).css({"background-image": "url(" + imgs[i][0] + ")", "background-position": imgs[i][1]});
        if (++i === imgs.length) { i = 0; }
    });    
});

Upvotes: 0

Nick Craver
Nick Craver

Reputation: 630349

Your counter variable isn't scoped right, you need one counter variable. Overall though, why not let .toggle() manage this for you? Here's what it would look like:

$(function() {
  $('body').toggle(function(){
     $(this).css({"background-image":"url(1.jpg)", "background-position":"40% 35%"});
  }, function() {
     $(this).css({"background-image":"url(2.jpg)", "background-position":"10% 35%"});
  }, function() {
     $(this).css({"background-image":"url(3.jpg)", "background-position":"10% 35%"});
  });
});

Although the name and common usages suggest that .toggle() only takes 2 functions, it actually takes 2 or more and will cycle through them.

Upvotes: 6

casablanca
casablanca

Reputation: 70691

Your counter declarations are strewn all over the place which makes it difficult to follow what's happening. Further, counter is declared local to the callback function, which means it loses its value every time the function executes.

Here's a simpler solution:

$(function() {  // this is equivalent to $(document).ready(...)
  var counter = 0;
  var images = [
    [ '1.jpg', '40% 35%' ],
    [ '2.jpg', '10% 35%' ],
    [ '3.jpg', '10% 35%' ]
  ];
  $('body').click(function() {
    $(this).css('background-image', 'url(' + images[counter][0] + ')');
    $(this).css('background-position', images[counter][1]);

    // increment counter, wrapping over to 0 when it reaches end of array
    counter = (counter + 1) % images.length;
  });
});

You can easily extend to this to any number of images by simply adding more entries to the images array.

Upvotes: 0

BrunoLM
BrunoLM

Reputation: 100322

Your function uses this which is refering to itself, not the element. This would fix it:

$('body').click((function(){
    var $this = $(this);
    return ... {
        $this // use $this instead of $(this)

Also, have a look on jQuery .toggle

Upvotes: 0

prodigitalson
prodigitalson

Reputation: 60413

this no longer refers to the body element, it refers to the anonymous function.

Upvotes: 1

jcolebrand
jcolebrand

Reputation: 16025

Does this code work?

var counter = 1;
$(document).ready(function() {
    $('body').click(function() {
        if (counter == null) {
            counter = 1;
        }
        if (counter == 3) {
            $(this).css("background-image", "url(3.jpg)");
            $(this).css("background-position", "10% 35%");
            counter = 1;
        }
        if (counter == 2) {
            $(this).css("background-image", "url(2.jpg)");
            $(this).css("background-position", "10% 35%");
            counter = 3;
        }
        if (counter == 1) {
            $(this).css("background-image", "url(1.jpg)");
            $(this).css("background-position", "40% 35%");
            counter = 2;
        }
    });
});

Upvotes: 0

Related Questions