Flow of events
JavaScript manipulation of CSS is called scripted CSS, and JavaScript interacts with HTML through events. Events are specific moments of interaction that occur in a document or browser window, and event flow (also known as event propagation) describes the order in which events are received from the page.
Three phases of the event flow
- Event capture phase
- In the target stage
- Event bubbling phase
Event capture
Events received earlier by less specific nodes (window/document) are propagated to specific nodes, and the most specific node should receive the event last.
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the minimum - scale = 1, maximum = 1, the user - scalable = no">
<title>Document</title>
<style type="text/css">
#box{
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
var box = document.getElementById("box");
box.addEventListener('click'.function(){
box.innerHTML += "div\n"
},true);//false indicates the bubbling phase
document.body.addEventListener('click'.function(){
box.innerHTML += "body\n"
},true);
document.documentElement.addEventListener('click'.function(){
box.innerHTML += "html\n"
},true);
document.addEventListener('click'.function(){
box.innerHTML += "document\n"
},true);
window.addEventListener('click'.function(){
box.innerHTML += "window\n"
},true);
</script>
</body>
</html>
Copy the code
The event bubbling
Events are initially received by the most concrete nodes and then propagated up the hierarchy to the less concrete nodes (documents)
Note: Following IE9 only bubbles up to document
The test code
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the minimum - scale = 1, maximum = 1, the user - scalable = no">
<title>Document</title>
<style type="text/css">
#box{
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
var box = document.getElementById("box");
box.onclick = function(){
box.innerHTML += "div\n"
}
document.body.onclick = function(){
box.innerHTML += "body\n"
}
document.documentElement.onclick = function(){
box.innerHTML += "html\n"
}
document.onclick = function(){
box.innerHTML += "document\n"
}
window.onclick = function(){
box.innerHTML += "window\n"
}
</script>
</body>
</html>
Copy the code
Event handler
Event handlers, also called event listeners, are essentially event binding functions. The corresponding code in the function is executed when the event occurs.
There are four types of event handlers:
- HTML event handler
- DOM 0-level event handlers
- DOM 2 level event handler
- IE event handler
HTML event handler
It is uncommon to bind events directly to elements
Inside the event handler function, this points to the target element of the event.
<div id="box" onclick="this.innerHTML+='1'"></div>Where this is the current object (<div id="box" onclick="this.innerHTML+='1'"></div>)
Copy the code
Is equivalent to
<div id="box" onclick="test()"></div>
<script type="text/javascript">
var box = document.querySelector("#box");
function test(){
console.log(this);// This refers to window, the function is called independently, and the inner this refers to window
box.innerHTML +='1';
}
</script>
Copy the code
disadvantages
HTML + JS is mixed together and not easy to maintain.
DOM 0-level event handlers
Attributes that assign a function to an event handler are widely used (simple, cross-browser)
Note:
Event handlers added at DOM 0 level are processed in the bubbling phase of the event flow; there is no capture phase
<div id="box"></div>
<script type="text/javascript">
var box = document.querySelector("#box");
box.onclick = function(){
this.innerHTML +='1';
}
// Delete the handler for the event
box.onclick = null;
</script>
Copy the code
disadvantages
You cannot bind the same event handler to the same element; if you do, the former will be overwritten
DOM 2 level event handler
There are two approaches to the handler
- addEventListener()
- removeEventListener()
addEventListener()
Event listener, addEventListener(” event name string “,function(){}, Boolean), where Boolean is false by default and may not be written, false indicates bubbling, and true indicates capture.
<div id="box"></div>
<script type="text/javascript">
var box = document.querySelector("#box");
box.addEventListener('click'.function(){
this.innerHTML +='1';
},false);
</script>
Copy the code
A DOM 2 level event handler that can bind the same event handler to the same element and be called at the same time.
Note:
Ie8 does not support DOM level 2 event handlers
Listeners pass arguments. You can wrap a listener with an anonymous function.
<div id="box"></div>
<script type="text/javascript">
var box = document.querySelector("#box");
box.addEventListener('click'.function(){
test(111);
},false);
function test(x){
alert(x);
}
</script>
Copy the code
removeEventListener()
Remove event
<div id="box"></div>
<script type="text/javascript">
var box = document.querySelector("#box");
box.addEventListener('click',handler,false);
function handler(){
this.innerHTML += 1;
}
box.removeEventListener('click',handler,false);
</script>
Copy the code
IE event handler
Available only in Internet Explorer, there are two ways to use the handler.
In IE this points to the window
- attachEvent()
- detachEvent()
attachEvent()
Add event
<div id="box"></div>
<script type="text/javascript">
var box = document.querySelector("#box");
box.attachEvent('onclick'.function(){
//this.innerHTML += '1';
// In IE, this points to window
box.innerHTML += '1';
});
</script>
Copy the code
detachEvent()
Remove event
<div id="box"></div>
<script type="text/javascript">
var box = document.querySelector("#box");
box.attachEvent('onclick',handler);
function handler(){
box.innerHTML += '1';
}
box.detachEvent('onclick',handler);
</script>
Copy the code
Event binding is compatible with writing
The following code
<body>
<button type="button">haha</button>
<script type="text/javascript">
var btn = document.querySelector("[type=button]");
// btn.addEventListener('click',fn,false);
// btn.attachEvent('onclick',fn);
addEvent(btn,'click'.function(){
console.log(this.innerHTML);
});
// Full browser event handler compatibility code
function addEvent(target,eventType,handler){
if(target.addEventListener){
target.addEventListener(eventType,handler,false);
}
else{
target.attachEvent('on'+eventType,function(){ handler.call(target); }); }}</script>
</body>
Copy the code
Event call sequence summary
The same
If both HTML event handlers and DOM0-level event handlers are present, the latter overrides the formerCopy the code
The difference between
Chrome, Safari, Firefox, or Internet Explorer 11 Result: Dom0 Level Dom2 level 2. Internet Explorer 9 and 10 Result: Dom0 level DOM2 Level 3. Internet Explorer 8 result: Dom0 level IECopy the code
The event object
When an event on the DOM is triggered, an event object is generated, which contains all the information related to the event
How do I get event objects
1. The event object is the first parameter of the event program, which is not supported by IE8
<body>
<div id="box"></div>
<script type="text/javascript">
window.onload = function(){
var box = document.getElementById("box");
box.onclick = function(e){ box.innerHTML = e; }}</script>
</body>
Copy the code
2. Use the Event variable directly, which is not supported by Firefox
<body>
<div id="box"></div>
<script type="text/javascript">
window.onload = function(){
var box = document.getElementById("box");
box.onclick = function(){ box.innerHTML = event; }}</script>
</body>
Copy the code
3. Compatible writing
<body>
<div id="box"></div>
<script type="text/javascript">
window.onload = function(){
var box = document.getElementById("box");
box.onclick = function(e){
e = e ||window.event; box.innerHTML = e; }}</script>
</body>
Copy the code
Event goals
There are three properties
- currentTarget
- target
- srcElement
currentTarget
Returns the node where the event is currently located, the node to which the listener is bound
<body>
<ul id="box">
<li class="item">1</li>
<li class="item">2</li>
</ul>
<script type="text/javascript">
var box = document.getElementById("box");
box.onclick = function(e){
e = e || event;
console.log(e.currentTarget);
var items = document.querySelectorAll("[class]");
items[0].innerHTML = e.currentTarget;//[object HTMLUListElement]
}
</script>
</body>
Copy the code
target
Returns the actual target object of the event
This object is the same as the E.currenttarget property, but ie8 is not supported
<body>
<ul id="box">
<li class="item">1</li>
<li class="item">2</li>
</ul>
<script type="text/javascript">
var box = document.getElementById("box");
box.onclick = function(e){
e = e || event;
console.log(e.target);
console.log(e.target===this);
// This object is the same as the e.currenttarget property
console.log(e.currentTarget===this);
var items = document.querySelectorAll("[class]");
items[0].innerHTML = e.target;//[object HTMLUListElement]
}
</script>
</body>
Copy the code
srcElement
Like the target attribute, but target does not support IE8, the srcElement attribute is not supported on earlier versions of Firefox
Compatible with
var box = document.getElementById("box");
box.onclick = function(e){
e = e || event;
var target = e.target || e.srcElement;
}
Copy the code
The event agent
Since the event will be passed up to the parent node in the bubbling phase, the listener function of the child node can be defined on the parent node, and the listener function of the parent node can uniformly handle the events of multiple child elements. This method is called event proxy, also called event delegate.
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0, the minimum - scale = 1, maximum = 1, the user - scalable = no">
<title>Document</title>
<style type="text/css">* {padding: 0;
margin: 0;
}
ul{
list-style: none;
overflow: hidden;
margin-top: 80px;
}
li{
width: 100px;
float: left;
height: 30px;
text-align: center;
line-height: 30px;
background-color: red;
margin: 0px 10px;
color: white;
}
</style>
</head>
<body>
<ul id="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script type="text/javascript">
window.onload = function(){
// Conventional methods
var lis = document.getElementsByTagName("li");
for (var i = 0; i<lis.length; i++){ lis[i].onmouseover =function(){
this.style.backgroundColor = 'blue';
}
lis[i].onmouseout = function(){
this.style.backgroundColor = 'red'}}// The event proxy is implemented by combining the event target object
var box = document.getElementById('box');
box.onmouseover = function(e){
e = e ||event;
var target = e.target || e.srcElement;
target.style.backgroundColor = 'blue'
}
box.onmouseout = function(e){
e = e ||event;
var target = e.target || e.srcElement;
target.style.backgroundColor = 'red'}}</script>
</body>
</html>
Copy the code
advantages
Improved performance and reduced code
The event bubbling
Event bubbling is the third phase of the event flow through which event responses can be made to events.
For bubbling, the event object contains four related properties and methods
- bubbles
- cancelBubble
- stopPropagation()
- stopImmediatePropagation()
bubbles
Returns a Boolean value indicating whether the current event will bubble. This property is read-only.
Note:
Most events that occur on a document bubble, but focus, blur, scroll events do notCopy the code
<body>
<button>button</button>
<input type="text" name="" id="" value="" />
<script type="text/javascript">
var btn = document.getElementsByTagName('button') [0];
var inP = document.querySelector('[type=text]');
btn.onclick = function(e){
e = e || window.event;
console.log(e.bubbles);//true
}
inP.onfocus = function(e){
e = e || window.event;
console.log(e.bubbles);//false
}
</script>
</body>
Copy the code
stopPropagation()
Represents further capture or bubbling of the cancelled event, with no return, not supported by IE8
<body>
<button>button</button>
<script type="text/javascript">
var btn = document.getElementsByTagName('button') [0];
btn.onclick = function(e){
e = e || window.event;
// Prevent bubbling
e.stopPropagation();
this.innerHTML = 'Stop bubbling';
}
document.body.onclick = function(e){
e = e || window.event;
console.log('body');
}
</script>
</body>
Copy the code
disadvantages
There is no way to prevent other listener functions from being called for the same event
<body>
<button>button</button>
<script type="text/javascript">
var btn = document.getElementsByTagName('button') [0];
btn.addEventListener('click'.function(e){
e = e || window.event;
e.stopPropagation();
this.style.backgroundColor = 'blue';
},false);
btn.addEventListener('click'.function(e){
e = e || window.event;
// e.stopPropagation();
this.innerHTML = 'Stopped';
},false);
document.body.onclick = function(e){
e = e || window.event;
console.log('body');
}
</script>
</body>
Copy the code
stopImmediatePropagation()
This prevents bubbling and prevents other listener functions from being called for the same event
<body>
<button>button</button>
<script type="text/javascript">
var btn = document.getElementsByTagName('button') [0];
btn.addEventListener('click'.function(e){
e = e || window.event;
e.stopImmediatePropagation();
this.style.backgroundColor = 'blue';
},false);
btn.addEventListener('click'.function(e){
e = e || window.event;
// e.stopPropagation();
this.innerHTML = 'Stopped';
},false);
document.body.onclick = function(e){
e = e || window.event;
console.log('body');
}
</script>
</body>
Copy the code
cancelBubble
Can only be used to prevent bubbling, not the capture phase. This value is read and write, defaults to false, and is set to true to cancel bubbling.
<body>
<button>button</button>
<script type="text/javascript">
var btn = document.getElementsByTagName('button') [0];
btn.onclick = function(e){
e = e || window.event;
e.cancelBubble = true;
console.log(e.bubbles);
}
document.body.onclick = function(e){
e = e || window.event;
console.log('body');
}
</script>
</body>
Copy the code
Compatible with
StopPropagation () and stopImmediatePropagation() Ie8 does not support E.cancelBubble = true; Full browser support, not standardCopy the code
<body>
<button>button</button>
<script type="text/javascript">
var btn = document.getElementsByTagName('button') [0];
btn.onclick = function(e){
e = e || window.event;
if(e.stopPropagation){
e.stopPropagation();
}
else{
e.cancelBubble = true;
}
this.innerHTML = 'modified'
}
document.body.onclick = function(e){
e = e || window.event;
console.log('body');
}
</script>
</body>
Copy the code
Event Flow phase (Understanding)
eventPhase
Returns an integer value representing the event flow phase in which the event is currently located
0 indicates that the event does not occur, 1 indicates the capture phase, 2 indicates the target phase, and 3 indicates the bubbling phase. Internet Explorer 8 does not support this.
<body>
<button type="button">Flow of events</button>
<script type="text/javascript">
var btn = document.getElementsByTagName('button') [0];
//2 Target phase
btn.onclick = function(e){
e = e || event;
console.log(e.eventPhase);
}
//1 Capture phase
document.body.addEventListener('click'.function(e){
e = e || event;
console.log(e.eventPhase);
},true)
//3 Bubble stage
document.body.addEventListener('click'.function(e){
e = e || event;
console.log(e.eventPhase);
},false)
</script>
</body>
Copy the code
Cancel the default event
Usual method
<a href="javascript:void(0);">baidu</a>
<a href="javascript:;">baidu</a>
Copy the code
Two methods in the event object that block the default event:
- preventDefault()
- returnValue
- return false
preventDefault()
Internet Explorer 8 is not supported
returnValue
Firefox and Internet Explorer 8 are not supported
return false
Tips, compatible with all browsers
<body>
<a href="#">baidu</a>
<a href="javascript:;">baidu</a>
<script type="text/javascript">
var item = document.getElementsByTagName('a') [0];
item.onclick = function(e){
e = e||event;
/* // preventDefault() e.preventDefault(); this.innerHTML = 'john'; * /
/* //returnValue e.returnValue = false; * /
// Compatible with IE8 or above
if(e.preventDefault){
e.preventDefault();
}else{
// Compatible with IE8 or below
e.returnValue = false;
}
/* / return false; * /
}
</script>
</body>
Copy the code
Event object properties
Mouse position
For coordinate positions, the event object provides clientX/Y, pageX/Y, screenX/Y, x/ Y, offsetX/Y, layerX/Y.
clientX/Y & x/y
The distance between the x and y axes relative to the browser (the valid area of the browser).
<body>
<div id="box"></div>
<script type="text/javascript">
var box = document.getElementsByTagName('div') [0];
box.onmousemove = function(e){
e = e || window.event;
console.log(e);
this.innerHTML = `clientX:${e.clientX}; clientY:${e.clientY}; x:${e.x}; y:${e.y}`
}
</script>
</body>
Copy the code
screenX/Y
The distance between the x and y axes relative to the display screen.
pageX/Y
The distance between the x and y axes of the page varies with the scroll bar
offsetX/Y
The distance between the x and y axes relative to the event source.