Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this wrong? (use of "this" with jQuery)

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script>
<script type="text/javascript">

        function bigtosmalltriangle() {
            $(this).siblings("div.break").removeClass('triangle3').addClass('triangle1');
            setTimeout ( "smalltomediumtriangle()", 400 );
        }
        function smalltomediumtriangle() {
            $(this).siblings("div.break").removeClass('triangle1').addClass('triangle2');
            setTimeout ( "mediumtobigtriangle()", 400 );
        }
        function mediumtobigtriangle() {
            $(this).siblings("div.break").removeClass('triangle2').addClass('triangle3');
            setTimeout ( "bigtosmalltriangle()", 400 );
        }

    $(function() {
        $("span#clickhere").click(
            function() {
                /* do a lot stuff here */ bigtosmalltriangle();
                $(this).hide();
            }
        );
    });
</script>

<style type="text/css">
    .triangle1 {background:#000;}
    .triangle2 {background:red;}
    .triangle3 {background:white;}
</style>

<div><div class="break">Hello World</div><span id="clickhere">asdf</span></div>

I'm trying to get get the div.break to scroll through 3 bgcolors, but when I click on the span it has no effect. Does anyone know what I should do?

Thanks.


2 Answers

You want to call your functions with a specific "this". I asked a similar question: Call function with "this".

$(function() {
        $("span#clickhere").click(
                function() {
                        /* do a lot stuff here */
                        bigtosmalltriangle.call(this);
                        $(this).hide();
                }
        );
});

I think because of closures (see Matthew Crumley's answer) the callback functions themselves don't need to be modified, because setTimeout keeps the "scope." I don't know Javascript enough to remotely guarantee that, though. If I am wrong, simply perform the .call(this) trick for the callback functions as well.

like image 108
3 revsstrager Avatar answered Jan 27 '26 15:01

3 revsstrager


The problem is that "this" is not bound to the span you clicked on in the bigtosmalltriangle, smalltomediumtriangle, and mediumtobigtriangle functions. You need to either pass in the element as a parameter, or set a variable that's in scope in all the functions through closures.

Parameter passing:

function bigtosmalltriangle(elements) {
    elements.removeClass('triangle3').addClass('triangle1');
    setTimeout(function() { smalltomediumtriangle(elements); }, 400);
}
function smalltomediumtriangle(elements) {
    elements.removeClass('triangle1').addClass('triangle2');
    setTimeout(function() { mediumtobigtriangle(elements); }, 400);
}
function mediumtobigtriangle(elements) {
    elements.removeClass('triangle2').addClass('triangle3');
    setTimeout(function() { bigtosmalltriangle(elements); }, 400);
}

$(function() {
    $("span#clickhere").click(
        function() {
            /* do a lot stuff here */
            bigtosmalltriangle($(this).siblings("div.break"));
            $(this).hide();
        }
    );
});

Closures:

$(function() {
    $("span#clickhere").click(
        function() {
            var elements = $(this).siblings("div.break");

            function bigtosmalltriangle() {
                elements.removeClass('triangle3').addClass('triangle1');
                setTimeout(smalltomediumtriangle, 400);
            }
            function smalltomediumtriangle() {
                elements.removeClass('triangle1').addClass('triangle2');
                setTimeout(mediumtobigtriangle, 400);
            }
            function mediumtobigtriangle() {
                elements.removeClass('triangle2').addClass('triangle3');
                setTimeout(bigtosmalltriangle, 400);
            }

            /* do a lot stuff here */
            bigtosmalltriangle();
            $(this).hide();
        }
    );
});
like image 38
asavage Avatar answered Jan 27 '26 15:01

asavage



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!