简体   繁体   中英

How do I pass additional parameters to the handlers in $.fn.hover()?

The documentation of jQuery's hover shows only one method of using the function:

$('.myClass').hover(function () {
    console.log('on mouse over');
},
function () {
    console.log('on mouse out');
});

However, when you change these to named functions it doesn't work correctly, firing the named functions upon page load (or as soon as you paste it into your console):

function onMouseOver() {
    console.log('on mouse over');
}

function onMouseOut()
    console.log('on mouse out');
}

$('.myClass').hover(onMouseOver(), onMouseOut());

Changing the last line to:

$('myClass').hover(onMouseOver, onMouseOut);

works as expected (firing on the event), but doesn't allow me to pass anything to the named functions. Is there any way to allow me to pass a variable to the functions?

Yes you need to use anonymous functions for this:

$('myClass').hover(function( e ) {
    onMouseOver( param1, param2... );
}, function( e ) {
    onMouseOut( param1, param2... );
});

You can pass variables into the named functions by calling it like so:

$('.myClass').hover(function() {
    onMouseOver(arg);
}, function() {
    onMouseOut(arg);
});

That's the only way to pass arguments, parameters into the named functions from that event.

This is a problem with function references vs. function invocation. Adding the "()" invokes the function (which in this case you'd be doing at binding time...effectively binding the result of the function rather than the function itself.

To pass arguments the simplest option would be to wrap the named function in an anonymous function (as @antyrat just posted).

And also no, this is not a quirk of hover, this is standard JavaScript (and most any other language that has first class functions).

As several others have noted, you'll have to use currying or binding to pass values to the functions. In the example where you wrote this:

$('.myClass').hover(onMouseOver(), onMouseOut());

you're actually calling the onMouseOver() and onMouseOut() methods immediately on that line, and not when the mouse actually moves over or out of the element; what you wrote is equivalent to writing this:

var mouseOverResult = onMouseOver();
var mouseOutResult = onMouseOut();
$('.myClass').hover(mouseOverResult, mouseOutResult);

That's definitely not what you want.

jQuery can only understand functions that are of the form function(event) , so if you want more parameters, or other parameters, you'll have to use currying to get them in there. Currying (named for the math professor who devised the concept) can be thought of as creating a new function where the values you want to pass are 'pre-bound' inside it.

So let's say you have a variable foo that you'd like to pass into your onMouseOver handler, like this:

function onMouseOver(foo) {
    ...
}

...

var foo = "Hello, World";

$('myClass').hover(...);

To be able to pass that value, you need another function that wraps up that foo and that onMouseOver with a function signature that jQuery can use. You do it like this:

function onMouseOver(foo) {
    ...
}

...

var foo = "Hello, World";

var curriedOnMouseOver = function(event) {
    onMouseOver(foo);
};

$('myClass').hover(curriedOnMouseOver);

As several others have suggested, you can avoid the extra variable declaration by creating the curried closure inside the hover() call:

function onMouseOver(foo) {
    ...
}

...

var foo = "Hello, World";

$('myClass').hover(function(event) {
    onMouseOver(foo);
});

This example above also shows how you would pass the event to your function as well, by simply adding more parameters to it:

function onMouseOver(event, foo, bar) {
    ...
}

...

var foo = "Hello, World";
var bar = "Goodbye, World";

$('myClass').hover(function(event) {
    onMouseOver(event, foo, bar);
});

JavaScript's functions --- or --- are incredibly powerful tools, and it would be worth your while to learn some of the things you can do with them, like these examples. 是非常强大的工具,值得您花些时间学习一些可以用它们完成的事情,例如这些示例。

The hover sugar method isn't really meant for complex scenarios.

In your case it would probably be better to use .on('mouseenter') and on('mouseleave') so that you can pass additional event data to each method, like

$('.myClass').on('mouseenter', {param1: val1}, onMouseOver).on('mouseleave', {param2: val2}, onMouseOut);

Then within your handlers you can access those params like so:

function onMouseOver(e) {
    console.log(e.data.param1);
}

function onMouseOut(e) {
    console.log(e.data.param2);
}

That's the sort of jQuery way to do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM