-1

I have a custom function called thisAnimate I'd like to call when an element is clicked. The problem is it works if I put the function inside an empty function using the jQuery on, but not if I use the function directly.

Why can't I use the function directly in the on function?

THIS CODE WILL WORK

var element = $(this);

element.on( 'click', function() {
    thisAnimate(element);
});

THIS CODE WILL NOT WORK ???

var element = $(this);

element.on( 'click', thisAnimate(element));
Cory Nickerson
  • 883
  • 2
  • 11
  • 19
  • 2
    because you are executing it and assigning what it returns to the click listener. There is also no reason why you need to pass element to that method. – epascarello Apr 09 '18 at 21:42
  • 1
    Because you invoke the function instead of passing reference to that function – Alon Eitan Apr 09 '18 at 21:43
  • 4
    Possible duplicate of [Why does click event handler fire immediately upon page load?](https://stackoverflow.com/questions/7102413/why-does-click-event-handler-fire-immediately-upon-page-load) – zero298 Apr 09 '18 at 21:43
  • `element.on( 'click', thisAnimate(element));` equals `let temp = thisAnimate(element);element.on( 'click', temp);` – Sphinx Apr 09 '18 at 21:45
  • epascarello, why wouldn't I need to pass the element variable to the function? When I'm trying to use `$(this)` in the function it doesn't work. – Cory Nickerson Apr 09 '18 at 21:49
  • `element` exists at a higher scope level. It will be available in all nested scopes. – Taplar Apr 09 '18 at 21:52
  • taplar, thats originally what I thought but it isn't working like that. Variables I am declaring in a higher scope don't seem to work in other functions. I'm still learning JS but I am adept at PHP so I have some understanding of how this should work. – Cory Nickerson Apr 09 '18 at 21:56
  • https://jsfiddle.net/gxawynkn/ javascript is not php. @CoryNickerson – Taplar Apr 09 '18 at 21:59
  • jsfiddle.net/zo6bo8gL I try it both with and without using the variable for thisElement in the function. Only works with. – Cory Nickerson Apr 09 '18 at 22:37
  • Because `thisElement` is not at the same or higher scope to `animateThis` in that fiddle. It is a nested variable in the callback for the each, which is at a lower scope than the `animateThis` function. @CoryNickerson – Taplar Apr 09 '18 at 22:44
  • http://jsfiddle.net/zo6bo8gL/15/ But still, you don't have to pass it in. – Taplar Apr 09 '18 at 22:48

2 Answers2

0

Because the second parameter of the on() function is a function to be executed, not the result of a function execution.

This code:

element.on( 'click', function() {
    thisAnimate(element);
});

Means, when the button is clicked, execute the anonymous function, which in turn executes the thisAnimate() function and passes it the element parameter. However, inside the anonymous function, this refers to the element that raised the event. So if you want to pass it to the thisAnimate() function, you should write:

element.on( 'click', function() {
    thisAnimate(this);
});

Although in your code, you declared the element variable at a higher scope, so it is accessible to the thisAnimate() function without having to pass it in a parameter.

Similarly, this code:

element.on( 'click', thisAnimate);

Means, when the button is clicked, execute the thisAnimate() function. It will be automatically passed the standard event parameters (e.g. event). Inside the thisAnimate() function, this refers to the element that raised the event.

But this code:

element.on( 'click', thisAnimate(element));

Means, when the button is clicked, execute the returned value of the thisAnimate() function. This obviously doesn't make any sense unless the thisAnimate() function returns a function. For most cases, this is an error. Again, the element variable is undefined.

Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
  • Appreciate the help. This is what I'm working on. jsfiddle.net/zo6bo8gL/12/ – Cory Nickerson Apr 09 '18 at 22:46
  • Taplar gave you the correct way to do it http://jsfiddle.net/zo6bo8gL/15/. Like I said, when you use the event properly `element.on( 'click', thisAnimate)`, you get `this` referring to the element that raised the event, so you don't need to pass it. But when you call `thisAnimate()` directly in your `else` branch, `this` will be the `window` object, so you have call it with a scoped `this` using the `call()` method like `animateThis.call(thisElement)`. – Racil Hilan Apr 10 '18 at 03:41
-1

The on method can be thought as:

element={
    on:function(nameOfEvent, callBackFunction){
        //
    }
};

now here 'callBackFunction' should refer to a function object. Because that function need to be called when 'nameOfEvent' will occur. if thisAnimate(element) returns a function object then element.on( 'click', thisAnimate(element)); would also work. But sadly this statement does not return a function object.

Ankush G
  • 989
  • 9
  • 14