Aditya Kappagantula
Aditya Kappagantula

Reputation: 562

JavaScript Closure Callback Itself

Here is the closure I wrote:

var slider = (function(){
    var count = 3;
    return function(){
        if (count>0) {
            $("#message").html("<h1>"+count+"</h1>");
            count--;
            $("#message").removeClass("animated zoomIn");
            $("#message").addClass("animated zoomIn");
            $("#message").one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",  function(){
                return slider();
            }());   
        } else{
            showCube();
        }
    }()
});

This closure gets executed by a jquery plugin:

$("#fishes").addClass("animated slideOutLeft").one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend", slider());

However, the callback is not getting executed. Can someone guide me in the correct direction please?

Upvotes: 1

Views: 144

Answers (1)

Amadan
Amadan

Reputation: 198324

The way I read it, you want slider() to return a closure you can use for one. However - it doesn't, as your code suffers from the premature execution syndrome.

Your slider function creates a closure, then immediately executes it, then returns the result of that execution. Since the inner closure has no return statements, the value returned from slider() is undefined, and one doesn't get any handler to attach.

Solution: remove the () from the second-to-last line. That should make slider() return a closure rather than its result.

EDIT: Your function() { return slider(); }() is equivalent to slider(), which constructs a new closure where count is 3. Replace it with arguments.callee, to provide the same closure that is executing right now.

var slider = (function(){
    var count = 3;
    return function(){
        if (count>0) {
            $("#message").html("<h1>"+count+"</h1>");
            count--;
            $("#message").one("click", arguments.callee);   
        } else{
            alert("The End");
        }
    }
});
$('#message').one('click', slider());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="message">Click me!</div>

Or, you can name it, so you can reference it directly:

var slider = (function(){
    var count = 3;
    return function sliderClosure(){
        if (count>0) {
            $("#message").html("<h1>"+count+"</h1>");
            count--;
            $("#message").one("click", sliderClosure);   
        } else{
            alert("The End");
        }
    }
});
$('#message').one('click', slider());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="message">Click me!</div>

Upvotes: 1

Related Questions