Hover event solution for multiple elements in jQuery

  • 2020-03-30 03:18:05
  • OfStack

1. Brief introduction of requirements

JQuery's hover event is for a single HTML element, for example:
 
$('#login').hover(fun2, fun2); 

The API, which calls the fun1 function when the mouse enters the #login element and the fun2 function when it leaves, already meets most of the requirements.

However, there are times when we want to trigger fun1 when the mouse enters two or more elements, and fun2 when it leaves them, and moving the mouse between those elements does not trigger any events. For example, an HTML element with two elements next to each other, as shown below:

< img SRC = "border = 0 / / files.jb51.net/file_images/article/201406/20140612154022.png? 2014512154048 ">  

Fun1 is triggered when the mouse enters the area of both and fun2 is triggered when it leaves. You might want to use the following
 
$('#trigger, #drop'),hover(fun1, fun2); 

This approach does not meet our needs, because fun2 and fun1 are triggered when we enter #drop from #trigger. An easy way to solve this problem is to change the HTML structure as follows:
 
<div id="container"> 
<div id="trigger"></div> 
<div id="drop"></div> 
</div> 

$('#container').hover(fun1, fun2); 

This is done by binding the hover event to the parent element.

2. Sample study

The following is a simplified diagram of the common drop-down menu. The HTML structure is as follows:

< img SRC = "border = 0 / / files.jb51.net/file_images/article/201406/201406121541174.gif? 2014512154132 ">  
 
ul id="#nav"> 
<li></li> 
<li></li> 
<li id="droplist"> 
<span> The drop-down menu </span> 
<ul> 
<li> The drop-down items 1</li> 
<li> The drop-down items 2</li> 
<li> The drop-down items 3</li> 
<ul> 
</li> 
<li></li> 
</ul> 

The javascript implementation is also very simple
 
$('#droplist').hover(function(){ 
$(this).find('ul').show(); 
}, function(){ 
$(this).find('ul').hide(); 
}); 

This implementation is logical, but it results in too many nested levels of HTML and a lot of inconveniences when writing CSS. Such as:
 
#nav li { font-size:14px; } 

We wanted this CSS to set a 14-pixel font for the first level li element, but it also applied to the second level element, so we had to rewrite it using the following statement
 
#nav li li { font-size:12px; } 

3. Solutions

Changing HTML structure
 
<ul id="#nav"> 
<li></li> 
<li></li> 
<li id="trigger"> The drop-down menu </li> 
<li></li> 
</ul> 
<ul id="drop"> 
<li> The drop-down items 1</li> 
<li> The drop-down items 2</li> 
<li> The drop-down items 3</li> 
<ul> 

Introduce the JS file in turn
 
<script type="text/javascript" src="js/jquery.js"></script> 
<script type="text/javascript" src="js/jquery.mixhover.js"></script> 

Control code
 
$.mixhover( 
'#trigger', 
'#drop', 
function(trg, drop){ 
#(drop).show(); 
}, 
function(trg, drop){ 
#(drop).hide(); 
} 
) 

In this way, when the mouse enters the #trigger, the #drop will be displayed. When the mouse moves from the #trigger to the #drop, no event will be triggered. In fact, the #trigger and the #drop elements are treated as one element.

The jquery. Mixhover. Js program is as follows
 
/** 
* Author: http://rainman.cnblogs.com/ 
* Date: 2014-06-06 
* Depend: jQuery 
*/ 
$.mixhover = function() { 
//Edit parameter $.mixhover($e1, $e2, handleIn, handleOut)
var parms; 
var length = arguments.length; 
var handleIn = arguments[length - 2]; 
var handleOut = arguments[length - 1]; 
if ($.isFunction(handleIn) && $.isFunction(handleOut)) { 
parms = Array.prototype.slice.call(arguments, 0, length - 2); 
} else if ($.isFunction(handleOut)) { 
parms = Array.prototype.slice.call(arguments, 0, length - 1); 
handleIn = arguments[length - 1]; 
handleOut = null; 
} else { 
parms = arguments; 
handleIn = null; 
handleOut = null; 
} 

//Sort out the parameters so that elements correspond in turn
var elems = []; 
for (var i = 0, len = parms.length; i < len; i++) { 
elems[i] = []; 
var p = parms[i]; 
if (p.constructor === String) { 
p = $(p); 
} 
if (p.constructor === $ || p.constructor === Array) { 
for (var j = 0, size = p.length; j < size; j++) { 
elems[i].push(p[j]); 
} 
} else { 
elems[i].push(p); 
} 
} 

//Bind Hover events
for (var i = 0, len = elems[0].length; i < len; i++) { 
var arr = []; 
for (var j = 0, size = elems.length; j < size; j++) { 
arr.push(elems[j][i]); 
} 
$._mixhover(arr, handleIn, handleOut); 
} 
}; 
$._mixhover = function(elems, handleIn, handleOut) { 
var isIn = false, timer; 
$(elems).hover(function() { 
window.clearTimeout(timer); 
if (isIn === false) { 
handleIn && handleIn.apply(elems, elems); 
isIn = true; 
} 
}, 
function() { 
timer = window.setTimeout(function() { 
handleOut && handleOut.apply(elems, elems); 
isIn = false; 
}, 10); 
}); 
}; 

Related articles: