in the web development process often encountered one needs to do is click on a div inside certain operations, while elsewhere click on the page to hide the div. For example, many navigation menu, when the menu expands, it will be asked to click on the page where other non-menu to hide the menu.
start with the most simple beginning, if the page has an id for the test of the div, we want to achieve elsewhere click on the page to hide the div:
<div id="test" style="margin:100px;background-color:#3e3;width:100px;height:100px;">
</div>
For this problem there are two ideas, these two ideas will use event bubbling this principle, you want to learn more about the event mechanism Javascript can look at JavaScript and HTML interact - Event , this is not the focus of this article, so here is a brief event bubbling,
event bubbling
IE bubbling event: Event start receiving the most concrete elements, and then progressively spread upward to the less specific elements
Netscape Event Capture: less specific node receives an earlier event, and the most specific elements of the last received event, and event bubbling opposite
DOM event flow: DOM2 level events specified event flow consists of three phases, event capture phase, in the target stage, event bubbling phase, the first occurrence of the event capture, the event provides an opportunity for the interception, and then the actual target receives events , the last sentence of the bubbling phase.
Opera, Firefox, Chrome, Safari all support the DOM event flow, IE does not support the flow of events, which only supports event bubbling
if the following html, click div region, according to the different elements of the model's click event triggers an event sequence is as follows:
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Test Page</title>
</head>
<body>
<div>
Click Here</div>
</body>
</html>
DOM on the trigger when an event will generate an event object event, this object contains all the information related to the incident, including the element generating the event, event type and other relevant information. All browsers support the event object, but supports different ways. Event object has a method (W3C: stopPropagation) / attributes (IE: cancelBulle = true) can prevent the event to continue bubbling or capture. If we want the event to an element prevents bubbling bubbling can write a compatible browser such methods:
function stopPropagation(e) {//把事件对象传入
if (e.stopPropagation) //支持W3C标准
e.stopPropagation();
else //IE8及以下浏览器
e.cancelBubble = true;
}
because all browsers support event bubbling, browser compatibility, we generally binding events will use it instead of event bubbling event capture. Understand this then we can look at the following two ideas.
thinking a
first idea in two steps
first step: the click event on the document to bind an event handler to hide the div
Step 2: div's click event binding event handlers to prevent event bubbling and prevent it from bubbling to document, document and call the onclick method hides the div.
<script type="text/javascript">
function stopPropagation(e) {
if (e.stopPropagation)
e.stopPropagation();
else
e.cancelBubble = true;
}
$(document).bind('click',function(){
$('#test').css('display','none');
});
$('#test').bind('click',function(e){
stopPropagation(e);
});
</script>
click on the page so that when non-div area when invoked directly or layers of bubbling document the onclick method to hide the div, and click the div when its child elements, events, always bubbling div itself, which When will prevent the event to continue bubbling doument not call the onclick method that results in div is hidden, thus completing our needs.
thinking two
we mentioned before, DOM on the trigger when an event will generate an event object event, this object contains all the information related to the incident, including the element generating the event, event type and other relevant information, ideas, a in the div click event handler argument passed is this event object. Visit the event object in IE there are several different ways, depending on the specified event handler method. DOM element directly add an event handler, event object as an attribute of the window object exists.
event object contains an important attribute: target (W3C) / srcElement (IE), this attribute identifies the original element that triggered the event, thinking two is to make use of this property. We can directly bind the click event on the document's event handler, the event handler for the interpretation of the event source id == test whether the div element or sub-element, the method return if it is not operating, if not then hide the div.
<script type="text/javascript">
$(document).bind('click',function(e){
var e = e || window.event; //浏览器兼容性
var elem = e.target || e.srcElement;
while (elem) { //循环判断至跟节点,防止点击的是div子元素
if (elem.id && elem.id=='test') {
return;
}
elem = elem.parentNode;
}
$('#test').css('display','none'); //点击的不是div或其子元素
});
</script>
so that when clicking anywhere on the page when the layers are bubbling to the document's click event, the event handler determines whether the event source div id == test of its child elements, if the method return, or hide the div, but also able to achieve our needs.
attention points and the pros and cons
these two ideas are dependent on the event bubbling, so we deal with other related elements in the click event when we must pay attention to this point, to avoid other related elements click event handler contains code to prevent event bubbling affect this function.
Both methods are easy to understand, looks like a better idea of some of it looks like it's easier to deal with some of the layers do not have to judge the event source, bind directly to the click event on the div. In this example, it does, but some pages do not necessarily complicated, and if we have a page with dozens div need to click on the page elsewhere hide such problems
<div class="dialogs">
<div class="dialog">
<div id="1">1</div>
<div id="2">2</div>
</div>
<div class="dialog">
<div id="1">1</div>
<div id="2">2</div>
</div>
<div class="dialog">
<div id="1">1</div>
<div id="2">2</div>
</div>
...
</div>
write the code might look like this:
<script type="text/javascript">
function stopPropagation(e) {
if (e.stopPropagation)
e.stopPropagation();
else
e.cancelBubble = true;
}
$(document).bind('click',function(){
$('.dialog').css('display','none');
});
$('.dialog').bind('click',function(e){
stopPropagation(e);
});
</script>
still looks simple way, but we think about it you will find problems, we are bound in each dialog on a similar approach, maintaining so many click event handler is definitely available for memory overhead , lead us page to run slowly. And if we can dynamically create a new dialog using ajax problem again, the newly created dialog can not be achieved hidden features! Because the binding function has been executed over, will not be binding for the new dialog click event handler, we can only do it by yourself this. That is not the idea of a handler to the DOM may not exist in the DOM element above. Because it is directly bound to each process element, it can not bind to the process elements present on the page.
this time is when the idea of two showcase their skills, and we look at this idea of two when writing code
<script type="text/javascript">
$(document).bind('click',function(e){
var e = e || window.event;
var elem = e.target || e.srcElement;
while (elem) {
if (elem.className && elem.className.indexOf('dialog')>-1) {
return;
}
elem = elem.parentNode;
}
$('#test').css('display','none');
});
</script>
change is quite small, and we take a look at the top is not able to solve the two problems, first of all no matter how many dialog we just bind a click event handler, has little effect on performance, add a new dialog thinking two code still good to make it, it's still so that, so that we can find in the case of complex pages actually thinking two is a better solution.
these have to understand, we can talk about this second protagonist of jQuery's delegate method.
delegate
first look at jQuery official delegate syntax and description
. delegate (selector, eventType, handler (eventObject))
Description: Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.
delegate () method for the specified element (belonging to the selected child elements) to add one or more event handlers, and provides run when these events occur when a function.
use delegate () method of the event handler for the current or future element (such as a new element created by the script).
$( "table" ).delegate( "td", "click", function() {
$( this ).toggleClass( "chosen" );
});
Through the above statement we can think of all table td bind click event handler.
delegate method design intent is to attach handlers to a single element or a group element on top of monitor events on the descendant elements rather than looping through and put the same function individually attached to the DOM elements on multiple . The handler attached to a (or a group) ancestor element rather than directly to the handler to all elements on the page, resulting in performance optimization.
jQuery version hidden dialog
Through the above knowledge we can find jQuery's delegate method makes it easy to achieve our demands hidden div
<script type="text/javascript">
$('.dialogs').delegate('.dialog','click',function(){
$(this).css('display','none');
});
</script>
using jQuery We found more than we thought two in terms of performance, there has been a slight increase, since we do not bubbling to the document processing, and only need the parent element in the dialog can be processed, you can not to put a lot of similar functions are bound to the document, the point to note is that jQuery has been attentive to help us put this deal as an event source to deal with them is like a duck it.
delegate and bind
Through the above we say that a bunch of us can weigh using bind or delegate has some basis, if an element on a single binding event handlers with bind is still very appropriate, but if you handle a lot of similar elements in the event When the handler may wish to consider delegate, to see if help to improve performance.
没有评论:
发表评论