Event model
When it comes to events, it goes back to Netscape's "Browser Wars" with Microsoft. At the time, the event model was not yet standard, and the implementation of two companies was a factual standard. Netscape implemented a "event capture" event system in Navigator, while Microsoft implemented an essentially opposite event system in IE called event bubbling. The difference between the two systems is that when an event occurs, the priority of the related element processing (responding) event is different.
The following examples illustrate the difference between the two event mechanisms. Suppose the document has the following structure:
Copy Code code as follows:
<div>
<span>
<a>...</a>
</span>
</div>
Because these three elements are nested, you click a and actually click Span and Div. In other words, all three elements should have an opportunity to handle a click event. Under event capture, the priority for handling this click event is: div > span > A; In the event bubbling mechanism, the priority for handling this click event is: a > span > div.
Later, the specification of the consortium required browsers to support both capture and bubbling mechanisms, and allow developers to choose which stage to register events. So we have the following standard method for registering the event:
Target.addeventlistener (type, listener, usecapture Optional);
which
Type: String that represents the type of event being monitored
Listener: Listener object (JavaScript function) that can be notified when a specified event occurs
Usecapture: Boolean value, whether to register to capture phase
In actual application development, to ensure compatibility with IE (because it does not support capture), Usecapture is generally specified as false (the default value is also false). In other words, just register the event into the bubbling phase; For the simple example above, the response order is: a > span > div.
bubbling side-effects
As mentioned earlier, the bubble event model of IE is basically a fact standard. But bubbling has a side effect.
Still take the previous document structure as an example, assuming that it is a menu item in the interface, we want the user to hide the menu when the mouse leaves the div. So, we registered a mouseout event for Div. If the user mouse is left from the Div, then everything is correct. And if the user's mouse is left from a or span, the problem comes. Because of the event bubbling, the Mouseout events from these two elements are propagated to the div, causing the mouse to not leave the Div, and the menu is hidden in advance.
Of course, the side effects of bubbling are not difficult to avoid. For example, register the Mouseout event for each element inside the div and use the. Stoppropagation () method to prevent the event from spreading further. For IE, you have to set the Cancelbubble property of the event object to False to cancel event bubbling. However, this still goes back to dealing with the problem of browser incompatibility.
Optimization Scheme
To avoid bubbling side effects, jquery provides MouseEnter and MouseLeave events, using them instead of mouseover and mouseout.
The following is an excerpt from the internal function withinelement of jquery, which provides support for MouseEnter and MouseLeave. Translated a note, for your reference only.
Copy Code code as follows:
The following function is used to detect whether an event occurred inside another element
Use in JQuery.event.special.mouseenter and MouseLeave handlers
var withinelement = function (event) {
Detects if Mouse (over|out) is still within the same parent element
var parent = Event.relatedtarget;
Set the correct event type
Event.type = Event.data;
Firefox sometimes assigns relatedtarget to a XUL element
For this element, you cannot access its ParentNode property
try {
Chrome is similar, although you can access the ParentNode property
But it turns out to be null.
if (parent && parent!== Document &&!parent.parentnode) {
Return
}
Up along the DOM tree
while (parent && parent!== this) {
parent = Parent.parentnode;
}
if (parent!== this) {
If it's actually right on top of a non child element, well, handle the event
JQuery.event.handle.apply (this, arguments);
}
Assume that you have left the element because it is possible that the mouse is placed on a XUL element
catch (e) {}
},
Conclusion
In jquery, you can use MouseEnter and MouseLeave events to avoid the side effects of event bubbling.
Original: http://www.ituring.com.cn/article/420