reperiendi

Greasemonkey closures

Posted in Programming by Mike Stay on 2006 September 27

I’m writing up a greasemonkey script that adds onclick behavior to the span. According to the site, you do something like

thisDiv.addEventListener('click',function(){
    // function code here
},true);

This works OK, but what if my code needs scope? Say I wanted to search for some divs and have them tell which match they are when clicked. This code won’t work:

for(i=0; i<allDivs.snapshotLength; i++){
    var thisDiv=allDivs.getSnapshotItem(i);
    thisDiv.addEventListener('click',function(){
        alert(i);
    },true);
}

If there were 10 matching divs, this will alert “10” every time. On the other hand, this code will work:

for(i=0; i<allDivs.snapshotLength; i++){
    var thisDiv=allDivs.getSnapshotItem(i);
    thisDiv.addEventListener('click',(function(i){return function(){
        alert(i);
    };)(i),true);
}

This is helpful when you want your modifications to retain access to functions like GM_setValue without using unsafeWindow. This way won’t work:

for(i=0; i<allDivs.snapshotLength; i++){
    var thisDiv=allDivs.getSnapshotItem(i);
    thisDiv.addEventListener('click',function(){
        GM_setValue('mydata',i);
    },true);
}

This way will:

for(i=0; i<allDivs.snapshotLength; i++){
    var thisDiv=allDivs.getSnapshotItem(i);
    thisDiv.addEventListener('click',(function(i,GM_setValue){return function(){
        GM_setValue('mydata',i);
    };)(GM_setValue,i),true);
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: