Object capture / delegate event / unblock event handler js

event

Binding event handler

  1. 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

  1. 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

  1. obj.attachEvent('onxxx',fn)
  div.attachEvent('onclick',function(){
        console.log('IE');
    })

Unique to IE, an event can also bind multiple handlers

  1. 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

  1. ele.onxxx = function(event){}

The program this points to the dom element itself

  1. obj.addEbentListener(type,fn,false);

The program this points to the dom element itself

  1. 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);
        }
  1. 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

  1. ele.onclick = null;
    var div = document.getElenmentsByTagName('div')[0];
    
    div.onclick = function(){
        consoloe.log('a');
        this.onclick = null;
    }
  1. 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
  1. ele.detachEvent('on' + type,fn);
  • If an anonymous function is bound, it cannot be released

Event handling mode – event bubbling, event capture

  1. 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
  1. 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
  1. 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);
  1. 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

  1. 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';
        }
  1. 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';
        }
  1. Encapsulation function
   function stopBubble(event){
            if(event.stopPropagation){
                event.stopPropagation();
            }else{
                event.cancelBubble = true;
            }
        }

Block default events

  1. Default event – form submission a tab, jump to right-click menu, etc
  2. return false; Events registered as object attributes take effect (e.onclick takes effect as a handle)
 document.oncontextmenu = function(){
            console.log('a');
            return false;
        }
  1. event.preventDefault(); W3C standard
 document.oncontextmenu = function(e){
            console.log('a');
            e.preventDefault();
        }
  1. event.returnValue = false, IE compatible
document.oncontextmenu = function(e){
            console.log('a');
            e.returnValue = false;
        }
  1. 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

  1. event || window.event for IE
  2. 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

  1. 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/

Keywords: Javascript

Added by tcarnes on Fri, 04 Mar 2022 13:57:51 +0200