Spoeken
Spoeken

Reputation: 2588

Javascript run a function at the same time with different vars

Sorry about the confusing title, I'll explain better. I have a 20x20 grid of div's, so its 400 of them each with an id, going from 0 to 399.

Each div is given one of three random values - red, green or blue - and when a div is clicked, a function is run to check if the div to the left, right, over and under are of the same value, if it is of the same value it will be simulated a click and the same function will run again.

The problem, is that the function sets vars, so if it finds that the div below has the same value, it will overwrite the vars set by the first click, hence never click any of the others.

JSfiddle - http://jsfiddle.net/5e52s/

Here is what I've got:

<!DOCTYPE html>  
<html lang="en">  
<head>
    <meta charset="utf-8"/>
    <title>untiteled</title>
    <style>
        body {
            width: 420px;
        }
        .box {
            width: 19px;
            height: 19px;
            border: 1px solid #fafafa;
            float: left;
        }

        .box:hover {
            border: 1px solid #333;
        }

        .clicked {
            background: #bada55 !important;
        }

    </style>

    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script>

        $().ready(function(){
            var colors = ['red', 'green', 'blue'];
            var i = 0;
            while(i<400){
                var color = colors[Math.floor(Math.random() * colors.length)];
                $('.test').append('<div class="box" id="'+i+'" value="'+color+'" style="background:'+color+';">'+i+'</div>');
                i++;
            }

            $('.box').click(function(){
                var t = $(this);
                t.addClass('clicked');
                id = t.attr('id');
                val = t.attr('value');

                //Set color

                up = parseInt(id) - 20;
                right = parseInt(id) + 1;
                down = parseInt(id) + 20;
                left = parseInt(id) - 1;
                clickup = false;
                clickdown = false;
                if($('#'+down).attr('value') === val){
                    clickdown = true;
                }
                if(up > -1 && ($('#'+up).attr('value') === val)){
                    clickup = true;
                }

                if(clickdown == true){
                    $('#'+down).click();
                }
                if(clickup == true){
                    $('#'+up).click();
                }







            });
        });

    </script>
</head>
<body>
    <div class="test">

    </div>      
</body>

Upvotes: 1

Views: 154

Answers (3)

wrongite
wrongite

Reputation: 918

I think the biggest root cause of your problem is you don't check if it already has class 'clicked' or not. That could make the infinite recursive. For example, if you click on the div#2 then the div#1 receives a simulated click, and div#2 receives a simulated click from div#1.

$('.box').click(function(){
    var t = $(this);
    if(t.hasClass('clicked')) {
        return;
    }

    t.addClass('clicked');
    var id = t.attr('id');
    var val = t.attr('value');

    //Set color

    var up = parseInt(id) - 20;
    var right = (id%20 != 19) ? ((0|id) + 1) : 'nothing' ;
    var down = parseInt(id) + 20;
    var left = (id%20 != 0) ? ((0|id) - 1) : 'nothing';

    console.log(up, right, down, left);

    if($('#'+down).attr('value') === val) {
       $('#'+down).click();                    
    }
    if($('#'+right).attr('value') === val) {
       $('#'+right).click();                    
    } 
    if($('#'+up).attr('value') === val) {
       $('#'+up).click();                    
    }
    if($('#'+left).attr('value') === val) {
       $('#'+left).click();                    
    }
});

Upvotes: 1

ErikE
ErikE

Reputation: 50211

Your variables id and val are not in a var statement, thus are implicitly created as members of the window object instead of being scoped to the local function. Change the semicolon on the line before each to a comma so that they become part of the var statement, and your code should begin working.

Upvotes: 0

Abdullah Jibaly
Abdullah Jibaly

Reputation: 54790

You can schedule the clicks onto the event loop instead of calling them directly, eg:

            if(clickdown == true){
                setTimeout(function () {
                  $('#'+down).click();
                });
            }

I don't think that's your root cause though, it's probably a combination of global vars and scope issues. Try reformatting as such:

$('.box').click(function (event){
    var t = $(this), id, val, up, right, down, left, clickup, clickdown;
    //...

Upvotes: 0

Related Questions