Registration for jQuery Conference 2008 is closed.

Sacrificial Lambda

Dynamically binding event handlers to content that has been ajaxed in with $.load without repeating yourself can be tricky. Lambda functions help you to not repeat yourself as much. jQuery uses lamdba functions everywhere, so if you're familiar with jQuery, you should be familiar with the syntax of lambda functions.

In this example, the ajaxed-in content contains the elements that trigger a $.load over themselves.

JavaScript:
  1. prepare_links = function() {   
  2.   var month = $('.calendar-info .month').html();   
  3.   var year = $('.calendar-info .year').html();   
  4.   $('.previous-month').click(function() {
  5.      $('#calendar').load(this.href, prepare_links);
  6.      return false;
  7.   });
  8.   $('.next-month').click(function() {
  9.      $('#calendar').load(this.href, prepare_links);
  10.      return false;
  11.   });
  12. };
  13. $(document).ready(function() {
  14.    prepare_links();
  15. });

Make sure you're not calling the function in the callback by accidentally using prepare_links():

JavaScript:
  1. $('.next-month').click(function() {
  2.    $('#calendar').load(this.href, prepare_links()); /* Don't do this */
  3.    return false;
  4. });

This would set the callback to whatever the return value of the function is, not to the function itself.

6 Responses to “Sacrificial Lambda”

  1. karl Says:

    Hey Dan,
    So, a "lambda function" is the same thing as an anonymous function, right?

  2. Patrick Hall Says:

    Thanks, I finally stumbled across this technique when I got sick of wrapping all the functions I wanted to run in $('document').ready() with function(){} wrappers. This way is much cleaner, it's nice to see that I'm on the right track with that.

    The recursion in prepare_links is also something new to me; I didn't realize that you could self-refer to a function definition in this way. Neat. Confusing, but neat.

    PS this blog is a great idea!

  3. Jörn Says:

    You could take this one step further and make it as DRY (Do not Repeat Yourself) as possible:

    CODE:
    1. do_load = function() {
    2.    $('#calendar').load(this.href, prepare_links);
    3.    return false;
    4. }
    5. prepare_links = function() {
    6.   $('.previous-month, .next-month').click(do_load);
    7. }
    8. $(document).ready(function() {
    9.    prepare_links();
    10. });

    I hope that code is readable...

  4. Jörn Says:

    Oops, it can be written even DRYer:

    do_load = function() {
    $(’#calendar’).load(this.href, prepare_links);
    return false;
    }
    prepare_links = function() {
    $(’.previous-month, .next-month’).click(do_load);
    }
    $(prepare_links);

    Heh.

  5. Marat Says:

    You have forgoten next moment. To set the whole construction callback to null. Your example overflows browser buffer.

    prepare_links = function() {
    prepare_links = false; ///!forgoten

    So, what do you thing about it?

  6. Sientz Says:
    
    prepare_links = function() {
    prepare_links = false; ///!forgotten
    
    

    Do I need to use that =false somewhere in my script? I have created a div_switch function that hides all my functions at the bottom, where would I insert the div_switch = false; if needed??

    
    $(document).ready(function(){
    
      //THIS HIDES ALL LISTED DIVS ON LOADING OF PAGE
      $('div.blackbook').hide();
      $('div.canvas').hide();
      $('div.pencil').hide();
      $('div.murals').hide();
      $('div.shows').hide();
      $('div.tattoos').hide();
      $('div.miscellaneous').hide();
    
      $('a#blackbook').click(function() {
        //HIDE DIVS
        hide_divs();
        //SHOW LISTED DIV
        $('.blackbook').show('fast');
        return false;
      });
    
      $('a#canvas').click(function() {
        //HIDE DIVS
        hide_divs();
        //SHOW LISTED DIV
        $('.canvas').show('fast');
        return false;
      });    
    
      $('a#pencil').click(function() {
        //HIDE DIVS
        hide_divs();
        //SHOW LISTED DIV
        $('.pencil').show('fast');
        return false;
      });    
    
      $('a#murals').click(function() {
        //HIDE DIVS
        hide_divs();
        //SHOW LISTED DIV
        $('.murals').show('fast');
        return false;
      });    
    
      $('a#shows').click(function() {
        //HIDE DIVS
        hide_divs();
        //SHOW LISTED DIV
        $('.shows').show('fast');
        return false;
      });    
    
      $('a#tattoos').click(function() {
        //HIDE DIVS
        hide_divs();
        //SHOW LISTED DIV
        $('.tattoos').show('fast');
        return false;
      });    
    
      $('a#miscellaneous').click(function() {
        //HIDE DIVS
        hide_divs();
        //SHOW LISTED DIV
        $('.miscellaneous').show('fast');
        return false;
      });    
    
    });
    
    //HIDES ANY VISIBLE DIVS
    
    hide_divs = function() {
    
        //HIDE ANY VISIBLE DIVS BEFORE CONTINUING
        if ($('div.main').is(':visible')) {
        $('div.main').hide('fast');
        }
        if ($('div.blackbook').is(':visible')) {
        $('div.blackbook').hide('fast');
        }
        if ($('div.canvas').is(':visible')) {
        $('div.canvas').hide('fast');
        }
        if ($('div.pencil').is(':visible')) {
        $('div.pencil').hide('fast');
        }
        if ($('div.murals').is(':visible')) {
        $('div.murals').hide('fast');
        }
        if ($('div.shows').is(':visible')) {
        $('div.shows').hide('fast');
        }
        if ($('div.tattoos').is(':visible')) {
        $('div.tattoos').hide('fast');
        }
        if ($('div.miscellaneous').is(':visible')) {
        $('div.miscellaneous').hide('fast');
        }
    }
    
    
    

    If there is an easier way to do this, please feel free to educate me, I am a rookie at this scripting stuff.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <pre> <em> <i> <li> <ol> <strike> <strong> <ul>

IMPORTANT: If you wish to post code examples, please wrap them in <code> tags. Multi-line code should be wrapped in <pre><code> </code></pre> Also, use &lt; instead of < and &gt; instead of > in the examples themselves. Otherwise, you could lose part of the comment when it's submitted.