Question

Description of Problem (Fiddle):

Clicking the red boxes turns them into kittens (and alerts you with the current value of i). Clicking the big kitten that fades in will reset everything.

I completely fail to understand why alert(i) is firing numerous times (seemingly escalating exponentially) on every subsequent passthrough after the first. Likewise, I do not understand how to prevent it from happening. My initial reaction was that it was creating new DOM elements, but I don't see how when I'm merely changing the img source.

Also, if my code is atrocious, feel free to point out flaws / clean it up. I always love learning more elegant approaches.

Code:

cats = [
    "http://placekitten.com/g/121/121",
    "http://placekitten.com/g/122/122",
    "http://placekitten.com/g/123/123",
    "http://placekitten.com/g/124/124",
    "http://placekitten.com/g/125/125",
    "http://placekitten.com/g/126/126",
    "http://placekitten.com/g/127/127",
    "http://placekitten.com/g/128/128",
    "http://placekitten.com/g/129/129",
    "http://placekitten.com/g/130/130"
];
count = 0;

function getRandomCats() {
    var kitties = [];
    for(i = 0; i < 3; i++) {
        rand = Math.floor(Math.random() * (9 - 0 + 1)) + 0;
        kitties[i] = cats[rand];
    }
    meow(kitties);
}

function meow(kitties) {
    $('.cats').each(function(i) {
        $(this).mousedown(function() {
            alert(i); //debug
            $('div.front img', this).attr('src', kitties[i]);
            $(this).css({
                'transform': 'rotateY(180deg)',
                '-webkit-transform': 'rotateY(180deg)',
                'transition': 'transform 500ms ease-in-out',
                '-webkit-transition': '-webkit-transform 500ms ease-in-out'
            });
            this.flipped = 1, this.locked;
            if (this.flipped && !this.locked) {
                this.locked = 1;
                count++;
                if (count > 2) {
                    $('#newCat').fadeIn();
                }
            }
        })
    });
}

var clicked = 0;
$('#newCat').mousedown(function() {
    if (clicked == 0) {
        clicked = 1;
        $(this).stop(true).fadeOut();
        $('.cats').fadeOut(1000, function() {
            this.flipped = 0, this.locked = 0, count = 0;
            $(this).hide().css({
                'transform': 'rotateY(0deg)',
                '-webkit-transform': 'rotateY(0deg)'
            });
            getRandomCats();
            $(this).fadeIn();
        });
    }
    setTimeout(function(){clicked = 0;}, 1000);
});

getRandomCats();
Was it helpful?

Solution

The mousedown statement does not overwrite the previously bound functions. You can easily solve this problem by putting

$(this).unbind("mousedown");

before the $(this).mousedown binding statement.

P.S. since you've asked about elegance: I would suggest you divide your code into more functions. Code becomes harder to read if you indent more than 2 levels. At some points you indent 5 or more levels.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top