One of the most common requirements in web development is to click inside a div to do something, and click on the page to hide the div elsewhere. For example, many navigation menus, when the menu is expanded, will be asked to click on other non-menu areas of the page to hide the menu.
Start with the simplest, if the page has a DIV with ID test, we want to implement a click on the page to hide the div elsewhere:
<id= "test" style= "Margin:100px;background-color: #3e3; width : 100px;height:100px; " > </ Div >
There are two general ideas for this problem, both of which will take advantage of the principle of event bubbling, and want to learn more about the JavaScript event mechanism to see the JavaScript and HTML interaction-Events, this is not the focus of this article, so here is just a brief description of event bubbling,
Event bubbling
Event bubbling of IE: the event starts with the most specific element received, then propagates up to the less specific element
Netscape event capture: Less specific nodes receive events earlier, while most specific elements receive events last, and event bubbling is reversed
Dom Event Flow: The DOM2 level event specifies that the event flow consists of three stages, an event capture phase, a target phase, an event bubbling phase, an event capture, an opportunity to intercept an event, an actual target receiving an event, and finally a bubbling sentence phase.
Opera, Firefox, Chrome, Safari all support DOM event stream, IE does not support event flow, only supports event bubbling
If you have the following HTML, click on the div area and follow the Click event Trigger order for the different model event elements as follows:
<!DOCTYPE HTML><HTML><Head> <Metahttp-equiv= "Content-type"content= "text/html; charset=utf-8" /> <title>Test Page</title></Head><Body> <Div>Click here</Div></Body></HTML>
Triggering an event on the DOM produces an event object that contains all the information related to the event, including information about the element that generated the event, the type of event, and so on. Event objects are supported for all browsing, but are supported in different ways. The event object has a method (W3c:stoppropagation)/property (Ie:cancelbulle=true) that prevents the event from continuing to bubble or capture. If we want to prevent bubbling when an event bubbles to an element, you can write a compatible browser method like this:
function stoppropagation (e) {//Pass event object to the if// support standard e.stoppropagation (); Else // IE8 and the following browsers true ; }
Because all browsers support event bubbling and browser compatibility considerations, we typically use event bubbling instead of event capture when binding events. After understanding this, we can look at the following two kinds of ideas.
Idea One
The first way of thinking is two steps.
First step: Bind the event handler to the document's Click event to hide the div
The second step is to bind the event handler to the Div's Click event, prevent the event from bubbling to the document, and call the document's OnClick method to hide the div.
<script type= "Text/javascript" > function Stoppropagation (e) { if (E.stop Propagation) e.stoppropagation (); else e.cancelbubble = true ' click ', function () {$ ( ' #test '). CSS (' Display ', ' None ' ' #test '). Bind (' click ', function (E) { Stoppropagation (e); }); </script>
This way, when you click on the page non-Div area, the direct or layer bubbling will call the document's OnClick method, hide the Div, and click on the DIV or its child elements, the event will always bubble the div itself, this time would prevent the event to continue bubbling, The Doument's OnClick method is not invoked to cause the div to be hidden, thus fulfilling our needs.
Two ideas
As we mentioned earlier, when triggering an event on the DOM, an event object is generated that contains all the information related to the event, including information about the element that generated the event, the type of event, and so on, and the parameters passed in by the Click event handler of the Div are the event object. There are several different ways to access an event object in IE, depending on how you specify the event handler. When you add an event handler directly for a DOM element, the event object exists as a property of the Window object.
The event object contains an important property: Target (Internet Explorer), which identifies the original element that triggered the event, and the second idea is to take advantage of the/srcelement property. We can bind the event handler directly to the document's Click event, and in the event handler, interpret whether the event source is an id==test div element or its child element, and if so, the method return does not do the operation, if not the div is hidden.
<script type= "Text/javascript" >$ (document). Bind (' Click ',function(e) {varE = e | | window.event;//Browser Compatibility varElem = E.target | |e.srcelement; while(Elem) {//loop judgment to the node, prevent the click is div child element if(elem.id && elem.id== ' test ') { return; } elem=Elem.parentnode; } $(' #test '). CSS (' Display ', ' none ');//The click is not a div or its child elements }); </script>
This will bubble up to the document's click event when clicking anywhere on the page, and the event handler will determine if the event source is a id==test div or its child elements, and if it is the method return, hiding the Div will also fulfill our needs.
Attention points and pros and cons
Both of these ideas depend on event bubbling, so we have to be aware of this when dealing with the Click event of other related elements, and to avoid the ability of the Click event handlers of other related elements to include blocking event bubbling code.
Both of these methods are easy to understand, looks like a better idea, it seems that its processing is more simple, do not have to layer to judge the event source, directly bind the click event to the Div. This is true in this case, but some of the complicated pages are not, if we have a page with dozens of div on it we need to click on the page to hide the problem elsewhere.
<Divclass= "Dialogs"> <Divclass= "Dialog"> <DivID= "1">1</Div> <DivID= "2">2</Div> </Div> <Divclass= "Dialog"> <DivID= "1">1</Div> <DivID= "2">2</Div> </Div> <Divclass= "Dialog"> <DivID= "1">1</Div> <DivID= "2">2</Div> </Div> ... </Div>
The code we write with our ideas may be:
<script type= "Text/javascript" > function Stoppropagation (e) { if (E.stop Propagation) e.stoppropagation (); else e.cancelbubble = true ' click ', function () {$ ( '. Dialog '). CSS (' Display ', ' None ' '. Dialog '). Bind (' click ', function (E ) {stoppropagation (e); }); </script>
It looks simple and still, but when we think about it, we'll find the problem, we've got a similar approach on every dialog, and maintaining so many click event handlers is absolutely overhead for memory, causing our pages to run slowly. And if we can dynamically use Ajax to create new dialog problems again, the newly created dialog cannot implement hidden features! Because the binding function has been executed and no more binding the Click event handler for the new dialog, we can only do it ourselves. In other words, one cannot attach handlers to DOM elements that may not yet exist in the DOM. Because it binds the handler directly to each element, it cannot bind the handler to an element that does not yet exist on the page.
This is the idea of the second show of skill, we look at the idea of two in this time the code of writing:
<script type= "Text/javascript" >$ (document). Bind (' Click ',function(e) {varE = e | |window.event; varElem = E.target | |e.srcelement; while(elem) {if(Elem.classname && elem.className.indexOf (' dialog ') >-1) { return; } elem=Elem.parentnode; } $(' #test '). CSS (' Display ', ' none ')); }); </script>
The change is also quite small, we have to see if we can solve the above two problems, first of all, no matter how many dialog we just bound a click event handler, the performance has little impact, add a new dialog thinking two of the code is OK, still good, In this way, we can find that in the case of complex pages, the second idea is actually a better solution.
These are all understood, and we can talk about the second protagonist of this article, the delegate method of jquery.
Delegate
First look at jquery's official syntax and description of delegate
. Delegate (selector, EventType, Handler (EventObject))
Description: Attach a handler to one or more events for all elements this match the selector, now or in the future, based on a specific Set of root elements.
The delegate () method adds one or more event handlers for the specified element (the child element of the selected element) and specifies the function to run when these events occur.
Event handlers that use the delegate () method apply to current or future elements, such as new elements created by a script.
function () { this). Toggleclass ("Chosen" ); });
With the above statement we can bind the Click event handler for all of the table's TD.
The delegate method is designed to attach a handler to a single element or to a small group of elements, listening to events on the descendant elements rather than looping through and attaching the same function to more than one element in the DOM. Attaching a handler to a (or a small group) ancestor element rather than attaching the handler directly to all the elements on the page, resulting in performance optimizations.
jquery version Hidden Dialog
Through the above knowledge we can find that the delegate method of jquery can easily realize our need of hiding Div.
<script type= "Text/javascript" > $ ('. Dialogs '). Delegate ('. dialog ', ' click ',function () { $ (this). CSS (' Display ', ' none '); }); </script>
Using jquery we find that there is a slight improvement in performance compared to our thinking, because we do not need to bubble to document processing, just need to dialog the parent element can be processed, can not have a lot of similar functions are bound to the document, One thing to be aware of is that jquery has been a thoughtful help for us to handle this as the source of the event, and to handle it is a duck.
Delegate and Bind
Through the above we say a bunch of we can use bind or delegate on a certain basis, if you are bound to a single element of the event handler, bind is very appropriate, but if you deal with many similar elements of event handlers, you might consider the delegate, See if it helps with performance improvements.
This article transferred from: http://www.cnblogs.com/dolphinX/p/3239530.html
Click on the page elsewhere to hide the delegate of the div's thought of jquery