1

I have about 12 div elements in a class called "item"

i have used for-loop to attach a onClick javascript function to each one of them:

for(var i = 0; i < $$(".item").length; i++){
    $$(".item")[i].observe("click", detailPopup);
}

so if I click any of the elements that are of "item" class, it'll run "detailPopup" function. But I want to pass a parameter to that function. More specifically, I want "this"() to be passed.

How do I do that??

I think I made my question as specific as possible, but in case I didn't, let me know, and I'll clarify my question.

THANKS!

Rob W
  • 341,306
  • 83
  • 791
  • 678
J.Ko
  • 964
  • 12
  • 26
  • You want to pass the current `this`, as in what the context was when this `for` loop ran?....or the clicked element itself? `this` should already refer to what you want in that case, just use the `this` keyword inside your `detailPopup` function. – Nick Craver Dec 06 '10 at 04:03

4 Answers4

2

You can bind this to the function:

for(var i = 0; i < $$(".item").length; i++){
    $$(".item")[i].observe("click", detailPopup.bind(this));
}

JSFiddle Example

subhaze
  • 8,815
  • 2
  • 30
  • 33
  • This is clever. `detailPopup`'s value of `this` will then be it's caller, instead of the element that triggered it as with normal events. – clockworkgeek Dec 06 '10 at 11:53
  • @clockworkgeek: Precisely, JavaScript frameworks are able to do this via the Function.apply() and Function.call() methods. Those two functions are pretty awesome. https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function – subhaze Dec 08 '10 at 05:01
2

Although I haven't explicitly tried this myself I believe you should be able to burn in your parameters.

$$('.item').invoke('observe', 'click', detailPopup.curry(this));

A reference to this will then be passed before all other parameters. Your function might look something like the following...

function detailPopup(parent, event)
{
    ...

The original meaning of this is preserved for the handler's scope, that of the triggered element. Also I used invoke to avoid all that messing around with index values and anonymous functions and stuff.

clockworkgeek
  • 37,650
  • 9
  • 89
  • 127
1

You'll want to create an anonymous function. In place of detailPopup, you should put something like: function() { detailPopup(that); }

What is that? Because the value of this isn't transferred to nested functions, you need to assign it to a variable before you can use it. Example: var that = this;

var that = this;

for(var i = 0; i < $$(".item").length; i++){
   $$(".item")[i].observe("click", function() { detailPopup(that); });
}
ClosureCowboy
  • 20,825
  • 13
  • 57
  • 71
0

You can do it like this:

for(var i = 0; i < $$(".item").length; i++){
    (function(t){
        $$(".item")[i].observe("click", function { detailPopup(t); });
    })(this);
}

the (function(t){ ... })(this); is a closure which ensures that this is the correct this otherwise you will get scoping issues. This is important in a few situations, for loops being one of them. If you didnt have a for loop you could have done this:

$$(".item")[i].observe("click", function { detailPopup(someParameter); });
Darko
  • 38,310
  • 15
  • 80
  • 107
  • What is the `(function...)(parameter)` form called? – clockworkgeek Dec 06 '10 at 23:30
  • its an anonymous self-executing function. Have a look at http://stackoverflow.com/questions/186024/how-do-you-explain-this-structure-in-javascript the first answer is correct. – Darko Dec 07 '10 at 00:32