SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Enthusiast
    Join Date
    May 2006
    Posts
    47
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Closures + array-value as parameter = kaboom

    Evening

    I have this very annoying problem, using JS closures. In the following code, this line makes my head go kaboom.

    Code:
    button.onclick   = function() { rte.rteCommand(buttons[i][0]); }
    When the onclick is triggered , it uses the buttons[i][0] , and not as it's value, example 'bold'. How can I make it do a copy, instead of a refference ? It's really nagging me..

    Code:
    var buttons = [['bold','bold-button','Bold']
                  ,['italic','italic-button','Italic']
                  ,['underline','underline-button','Underline']
                  ,['strikethrough','strike-button','Strikethrough']
                  ,['superscript','super-button','Superscript']
                  ,['subscript','sub-button','Subscript']
                  ,['justifyleft','justify-left-button','Justify left']
                  ,['justifycenter','justify-center-button','Justify center']
                  ,['justifyright','justify-right-button','Justify right']
                  ,['justifyfull','justify-full-button','Justify full']
                  ,['inserthorizontalrule','hr-button','Horisontal ruler']
                  ,['insertorderedlist','ordered-list-button','Ordered list']
                  ,['insertunorderedlist','unordered-list-button','Unordered list']
                  ,['outdent','outdent-button','Outdent']
                  ,['indent','indent-button','Indent']]
    var button;
    for(var i=0;i<buttons.length;i++) {
        button = lowerToolbar.appendChild(document.createElement('a'));
        button.className = buttons[i][1];
        button.title     = buttons[i][2]
        button.onclick   = function() { rte.rteCommand(buttons[i][0]); }
    }

  2. #2
    SitePoint Guru
    Join Date
    Sep 2006
    Posts
    731
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by thedeathart
    Evening

    I have this very annoying problem, using JS closures. In the following code, this line makes my head go kaboom.

    Code:
    button.onclick   = function() { rte.rteCommand(buttons[i][0]); }
    When the onclick is triggered , it uses the buttons[i][0] , and not as it's value, example 'bold'. How can I make it do a copy, instead of a refference ? It's really nagging me..
    I'm not certain, but try:

    button.onclick = new Function( "rte.rteCommand(buttons["+i+"][0])" );

  3. #3
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    button.onclick = function() { rte.rteCommand(buttons[i][0]); }
    The reason why this doesn't work is that closures are lazy and don't bind variables until they go out of scope, that is, all closures created in a loop will use the last value of the counter (i).

    "new Function" is ok, because it converts closure to an ordinary lambda. Another approach is to add an extra scope, thus forcing closures to bind at declaration time:

    Code:
    button.onclick  = function(k) { 
        return function() { rte.rteCommand(buttons[k][0]); }
    }(i)

  4. #4
    SitePoint Enthusiast
    Join Date
    May 2006
    Posts
    47
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    nicer solution that the one I picked thanks all.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •