event
Binding event handler
- ele.onxxx = function(event){}
<div onclick="console.log('a')"></div> var div = document.getElenmentsByTagName('div')[0]; div.onclick = function(){ this.style.backgroundColor = 'green'; }
Good compatibility, but only one handler can be bound to the same event of an element, which is basically equivalent to writing between HTML lines
- obj.addEventListener(type,fn,false) event type, handler function false
var div = document.getElenmentsByTagName('div')[0]; div.addEventListener('click',text,false); div.addEbentListener('click',text2,false); function text(){ console.log('a'); } function text2(){ console.log('b'); }
The w3c standard can bind multiple handlers for an event
- obj.attachEvent('onxxx',fn)
div.attachEvent('onclick',function(){ console.log('IE'); })
Unique to IE, an event can also bind multiple handlers
- Listen for event for loop closure problem
let liCol = document.getElenmentsByTagName('li'), len = liCol.length; for(let i = 0;i<len;i++){ (function(i){ loCol[i].addEventListener('click',function(){ console.log(i); //A closure is formed here },false); }(i)) }
Running environment of event handler
- ele.onxxx = function(event){}
The program this points to the dom element itself
- obj.addEbentListener(type,fn,false);
The program this points to the dom element itself
- obj.attachEvent('onxxx',fn);
The program this points to window
Solve the problem of this pointing and let this point to obj Call change this point
var div = document.getElenmentsByTagName('div')[0]; div.attachEvent('onclick',function(){ handle.call(div); }) function handle(){ console.log(this); }
- addEvent(elem,type,handle) for encapsulation compatibility; method
function addEvent(elem,type,handle){ if(elem.addEventListener){ elem.addEventListener(type,handle,false); }else if(elem.attachEvent){ elem.attachEvent('on' + type ,function(){ handle.call(elem); }) }else{ elem['on' + type] = handle; } }
Dismiss event handler
- ele.onclick = null;
var div = document.getElenmentsByTagName('div')[0]; div.onclick = function(){ consoloe.log('a'); this.onclick = null; }
- ele.removeEventListener(type,fn,false);
var div = document.getElenmentsByTagName('div')[0]; div.addEventListener('click',text,false); function text(){ console.log('a'); } div.removeEventListener('click',text,false); //Anonymous functions cannot unbind events
- ele.detachEvent('on' + type,fn);
- If an anonymous function is bound, it cannot be released
Event handling mode – event bubbling, event capture
- Event bubble false
Structurally (non visually) nested elements have the function of event bubbling, that is, the same event bubbles from the child element to the parent element. (bottom up)
<div class="wrapper" style="width: 300px;height:300px;background-color:red"> <div class="content" style="width: 200px;height:200px;background-color:yellow"> <div class="box" style="width: 100px;height:100px;background-color:green"></div> </div> </div> let wrapper = document.getElementsByClassName('wrapper')[0] let content = document.getElementsByClassName('content')[0] let box = document.getElementsByClassName('box')[0] wrapper.addEventListener('click',function(){ console.log('wrapper') },false); content.addEventListener('click',function(){ console.log('content') },false); box.addEventListener('click',function(){ console.log('box') },false); box content wrapper
- Event capture true
Structurally (not visually) nested elements have the function of event capture, that is, the same event is captured from the parent element to the child element (event source element). (top down)
IE did not capture events
<div class="wrapper" style="width: 300px;height:300px;background-color:red"> <div class="content" style="width: 200px;height:200px;background-color:yellow"> <div class="box" style="width: 100px;height:100px;background-color:green"></div> </div> </div> let wrapper = document.getElementsByClassName('wrapper')[0] let content = document.getElementsByClassName('content')[0] let box = document.getElementsByClassName('box')[0] wrapper.addEventListener('click',function(){ console.log('wrapper') },true); content.addEventListener('click',function(){ console.log('content') },true); box.addEventListener('click',function(){ console.log('box') },true); wrapper content box
- Trigger sequence: first capture, then bubble
<div class="wrapper" style="width: 300px;height:300px;background-color:red"> <div class="content" style="width: 200px;height:200px;background-color:yellow"> <div class="box" style="width: 100px;height:100px;background-color:green"></div> </div> </div> let wrapper = document.getElementsByClassName('wrapper')[0] let content = document.getElementsByClassName('content')[0] let box = document.getElementsByClassName('box')[0] wrapper.addEventListener('click',function(){ console.log('wrappermaopao') },false); content.addEventListener('click',function(){ console.log('contentmaopao') },false); box.addEventListener('click',function(){ console.log('boxmaopao') },false); wrapper.addEventListener('click',function(){ console.log('wrapperbu') },true); content.addEventListener('click',function(){ console.log('contentbu') },true); box.addEventListener('click',function(){ console.log('boxbu') },true);
- Focus blur change submit reset select and other events do not bubble
Cancel bubbling
There is a parameter e/event in the event function, which is the parameter penetrated by the system and represents the state when the event occurs
- event.stopPropagation(); w3c standard
document.onclick = function(){ console.log('click document event') //The default bubble point will execute this sentence everywhere } let div = document.getElementsByTagName('div')[0]; div.onclick = function(e){ e.stopPropagetion(); //Stop bubbling this.style.backgroundColor = 'red'; }
- event.cancelBubble = true; IE standard (Google also has)
document.onclick = function(){ console.log('click document event') //The default bubble point will execute this sentence everywhere } let div = document.getElementsByTagName('div')[0]; div.onclick = function(e){ // e.stopPropagetion(); // Stop bubbling e.cancelBubble = true; this.style.backgroundColor = 'red'; }
- Encapsulation function
function stopBubble(event){ if(event.stopPropagation){ event.stopPropagation(); }else{ event.cancelBubble = true; } }
Block default events
- Default event – form submission a tab, jump to right-click menu, etc
- return false; Events registered as object attributes take effect (e.onclick takes effect as a handle)
document.oncontextmenu = function(){ console.log('a'); return false; }
- event.preventDefault(); W3C standard
document.oncontextmenu = function(e){ console.log('a'); e.preventDefault(); }
- event.returnValue = false, IE compatible
document.oncontextmenu = function(e){ console.log('a'); e.returnValue = false; }
- Encapsulate the function cancelHandler();
document.oncontextmenu = function(e){ console.log('a'); cancelHandler(e); } function cancelHandler(e){ if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } }
Event object
- event || window.event for IE
- Event source object
event.target Firefox
event.srcElement IE
chrome has both
div.onclick = function(e){ let event = e || window.event; let target = event.target || event.srcElement; console.log(target); }
Event delegation
Use event bubbling and event source object for processing
Advantages, performance, flexibility, no need to bind one by one, and no need to rebind new child elements
- Click li in ul to output the value of this li (a lot of li)
let ul = document.getElementsByTagName('ul')[0]; ul.onclick = function(e){ let event = e || winodow.event; let target = event.target || event.srcElement; console.log(target.innerText); }
Original address: https://www.qianqianhaiou.cn/index.php/archives/92/