1

If I do the following:

image[i].onmousedown = whatever;

It will work perfectly fine and run the whatever() function on click. However if I do the following:

image[i].onmousedown = whatever( name, what, when, where, how );

It will run the function when it assigns the property. Let's say I create 30 images and want to give them all onmousedown functions, it will run that function 30 times on load just because I added the () after whatever. But how else do I assign my functions the properties I want?

Is the only way to make a function run the function? So do something like

image[i].onmousedown = whatever;

function whatever() {
   anotherWhatever( this, name, what, when, where, how );
}

I also have to assign a new value to 'this' it seems? What would you guys suggest or please tell me you have a better way of doing it. Thanks in advance for any help

Hate Names
  • 1,586
  • 1
  • 12
  • 20
  • `anotherWhatever.call( this, name, what, when, where, how );` – Musa Jun 22 '13 at 01:36
  • Hello again my 35k rep friend! :] Thanks for replying, brb looking into the .call syntax ! – Hate Names Jun 22 '13 at 01:37
  • @Musa not call need to use bind. Call will invoke it immediately. So `image[i].onmousedown = anotherWhatever.bind( this, name, what, when, where, how )` – PSL Jun 22 '13 at 01:37
  • @PSL bind on `whatever`, or call on `anotherWhatever` – Musa Jun 22 '13 at 01:40
  • @Musa oh yeah, but guess using bind on whatever would be fine?? what you think? – PSL Jun 22 '13 at 01:40
  • Hey thanks for all your guys's help. Is there any big difference between bind and call? Id prefer to use .bind so I don't have to create a second function just to run my original function? – Hate Names Jun 22 '13 at 01:48
  • 1
    There's a big difference between `.bind()` and `.call()`, one returns another function that is like a proxy to your function, while the other calls your function immediately. Use `.bind()` if you want to assign the result directly to `.onmousedown` - it will return a function that has the correct `this` and other parameters. Use `.call()` if you want to do the `anotherWhatever()` thing - it will call that other function immediately with the correct `this` and other params. – nnnnnn Jun 22 '13 at 01:51
  • 1
    Regarding your 30 images, if they're all going to be assigned essentially the same function that seems a good case for event delegation. – nnnnnn Jun 22 '13 at 01:53
  • @nnnnnn he is not using jquery though.. @ HateNames if you are using jquery then this would be a cake walk as nnnn suggests. – PSL Jun 22 '13 at 01:54
  • @PSL - I didn't mention jQuery, though yes: it can make this sort of thing easier. – nnnnnn Jun 22 '13 at 01:55
  • Nope I'm not using jQuery unfortunately. But from what I just searched it seems like I can use it in regular JS? Either way thanks so much nnnnn for giving me tips beyond my question,I really love that sort of thing. Thanks so much for all the help – Hate Names Jun 22 '13 at 01:56
  • The "event delegation" concept basically means that you assign the mousedown handler to a parent element instead of to the individual img elements (in your case). If they don't have a common parent you can assign the handler to the document. The event "bubbles up" from the target element (your img(es)) to the parent, where you can tell what the particular target was via properties of the `event` object. Here's the first short tutorial I found via Google: http://davidwalsh.name/event-delegate – nnnnnn Jun 22 '13 at 02:01
  • I also found: http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation – Hate Names Jun 22 '13 at 02:02
  • Yes, Crescent Fresh's answer to that other question is what I'm talking about (the other answers don't apply because they were written for the original version of the question which was much too vague). – nnnnnn Jun 22 '13 at 02:06

2 Answers2

2

You can use ecmaScript5 bind function, to bind the context and set the arguments to be passed in.

image[i].onmousedown = whatever.bind(this, name, what, when, where, how );  

this here will be the current context where you are binding the event. If you want to get the context of the element itself then:

image[i].onmousedown = whatever.bind(image[i], name, what, when, where, how );  

As mentioned in MDN you can place this script in your js for older browser support.

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}
PSL
  • 120,386
  • 19
  • 245
  • 237
  • As indicated by the mention of ecmaScript5, note that `bind` is only available in modern browsers...if you have jQuery loaded, you can use `jQuery.proxy`; alternatively you can use a shim for it such as the one here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fbind – Matt Browne Jun 22 '13 at 01:40
  • Hey thanks for all your help. I was just about to ask you about this since the result of this gives me the entire image 'array' or all the values of image instead of the actual 'this'. But you answered before I could ask you. I tried your thing but I didn't think it'd work and it didn't, since giving the value image[i] will return what value i is when clicked? Would you know how I could get the number of the one I clicked on? Or is there a better way to do it. Thanks once again for all your help, +1 – Hate Names Jun 22 '13 at 01:47
  • 1
    @HateNames Yes sure. Could you just prepare a fiddle? – PSL Jun 22 '13 at 01:48
  • I think by the time i'd prepare the fiddle I might have it figured out so I'll continue working with it, you guys gave me enough to go on, thank you very much for all your help! – Hate Names Jun 22 '13 at 01:54
1

You need to wrap it in an anonymous function:

image[i].onmousedown = function () { whatever.call(this, name, what, when, where, how ); };
Platinum Azure
  • 41,456
  • 9
  • 100
  • 130
  • This kinda works, only problem is it doesn't take 'this' with it. so I'd have to do image[i].onmousedown = function () { whatever( this, name, what, when, where, how ); }; instead. +1 for more possibilities – Hate Names Jun 22 '13 at 02:34
  • Sorry, my mistake. Edited to fix that. – Platinum Azure Jun 22 '13 at 06:31