In depth understanding of four ways to set up event handlers in JS

  • 2021-07-26 06:16:19
  • OfStack

The scope of all JavaScript event handlers is executed in the scope in which they were defined, not the scope in which they were called, and they can access any 1 local variable in that scope. However, the HTML tag attribute registration handler is an exception. Look at the following four ways:

Mode 1 (HTML tag attribute):


<input type="button" id="btn1" value=" Test " onclick="alert(this.id);" />

The above code adds a click event to button by setting the HTML tag attribute. When button button is clicked, id of button, that is, btn1, will pop up.

This registration of event handlers through the HTML property is an exception. They are converted to top-level functions that can access global variables instead of any local variables. For historical reasons, they run in a modified scope chain. Event handlers defined by the HTML property can use the properties of the target object, container object (form) object, and document object, just like local variable 1. It will be converted by the browser into code similar to the following:


 function (event){
  with(document){
   with(this.form||{}){
    with(this){
     /* Specific event handling code */
    }
   }
  }  
}

The usage of with can be consulted by yourself, and there are articles explaining it later here. Readers should know for themselves first. 1 connection available (https://developer. mozilla. org/zh-CN/docs/Web/JavaScript/Reference/Statements/with)

This method is no longer recommended.

Mode 2 (calling function)


<input type="button" id="btn2" value=" Test " onclick="test()" />
<script type="text/javascript">
  function test(){
   alert(this.id);
  }
</script>

This code pops up with undefined.

This setting mode is carried out by calling the global function. At this time, this points to window, not the caller of this button, and can output console. log (this==window); To validate

Mode 3 (calling function)


<input type="button" id="btn3" value=" Test " />
<script type="text/javascript">
   var btn3 = document.getElementById("btn3");
        btn3.onclick = function () {
          alert(this.id);
        };
</script>

This code pops up with btn3.

Such event handlers are defined on the event target, so they are called as methods of the object (with an exception in IE below). That is to say, within the event handler, the this keyword refers to the event target.

When registered with addEventListener (), the called handlers use the event target as their this value. But for handlers that are also registered with attachment () as function calls, their this values are global (window) objects. That is to say, the fourth way

Mode 4 (via addEventListener and attachment):


<input type="button" id="btn3" value=" Test " onclick="test()" />
 var btn = document.getElementById("btn3");
        var handler = function () { console.log(this.id); };
        if (btn.addEventListener) {
          console.log("addEventListener");
          btn.addEventListener("click", handler, false);
        }
        else if (btn.attachEvent) {//IE9 Previous versions 
          console.log("attachEvent");
          btn.attachEvent("onclick",handler);
        }

The output in IE5-IE8 is undefined. (attachement is called.)

btn3. Output from IE9 after IE9 (fixed the problem above and added the generic addEventListener).

If you want to fix the problem in IE5-8, you can use the following method.


/*
*target: Target object ,button Something like that 
*type:"click" String event name , No need to bring on
*handler: Called handler 
*/
function addEvent(target,type,handler){
 if (target.addEventListener) {
          target.addEventListener(type, handler, false);
        }
        else if (target.attachEvent) {//IE9 Previous versions           
          btn.attachEvent("on"+type,function(event){
            return hanlder.call(target,event);// Method call with handler as event target , Change this Point to. 
          });
        }
}

Related articles: