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.