原生JS 从DOM事件流到事件处理浏览器解决适配模板(DOM探秘吧!)

本文介绍了一种跨浏览器的事件处理机制,包括事件处理的基本概念、不同浏览器间的差异性处理及性能优化策略。通过实例展示了如何统一处理不同浏览器的事件绑定与解除绑定。

前言:

       世界上的浏览器分两种,一种叫IE(嗯,从win10开始没有了变成了Edge,但是有时候还是需要做IE的兼容),一种叫其它。在个人学习中我们无论写静态还是写点简单的交互操作,往往是只要在Chrome上正常即可,不会注意兼容性问题,感觉很失败。而就现在阶段而言个人理解的兼容问题就在于不同浏览器的操作API上。

|注:博文仅供参看,且看且思考。欢迎提错.|

事件处理浏览器解决适配模板(通配板)

  // 简单包装功能基础,还是有很多处理可以添加。
      var EventUtil={
        // 添加事件处理
        addHandler:function(ele,type,handler){
            if (ele.addEventListener) {
              ele.addEventListener(type,handler,false);
            }else if (ele.attachEvent) {
              ele.attachEvent('on'+type,handler);
            }else {
              ele['on'+type]=handler;
            }
        },
        // 移除事件处理
        removeHandler:function(ele,type,handler){
          if (ele.removeHandler) {
            ele.removeHandler(type,handler,false);
          }else if (ele.detachEvent) {
            ele.detachEvent('on'+type,handler);
          }else {
            ele['on'+type]=null;
          }
        },
        //得到事件对象 
        getEvent:function(event){
          return event?event:window.event;
        },
        // 得到事件目标
        getTarget:function(event){
          return event.textarea||event.srcElement;
        },
        // 阻止冒泡
        preventDefault:function(event){
          if (event.preventDefault) {
            event.preventDefault();
          } else {
            event.returnValue=false;
          }
        },
        // 阻止事件默认行为
        stopPropagation:function(event){
          if (event.stopPropagation) {
            event.stopPropagation();
          } else {
            event.cancelBubble=true;
          }
        }
      }

|注:这是最终目的。有兴趣可以往下看!|

DOM事件:

交互网页,JS通过事件监听(捕获事件),事件处理,事件冒泡完成。简单点你可以理解DOM操作就是一套JS操作HTML元素的API。

  1. 事件冒泡:具体一个发出事件的元素往上(父级元素)传,至document文档对象。例:

      <div class="" onclick="alert('father')">
      <button type="button" name="button" onclick="alert('son')">click</button>
    </div>
  2. 事件默认行为:例如点击a标签默认页面发生跳转。

事件处理程序:

  1. HTML内嵌:
    例如:
      <button type="button" name="button" onclick="alert('son')">click</button>
  缺点:太丑,变动麻烦。好吧,感觉主要是丑。

2. DOM0级:

      <button id="but" type="button" name="button">click</button>
    <script type="text/javascript">
      var but=document.getElementById('but');
      but.onclick=function(event){
        alert('son');
      }
      but.onclick=null;
    </script>
  1. DOM2级:
      <button id="but" type="button" name="button">click</button>
    <script type="text/javascript">
      var but=document.getElementById('but');
      function sayName(event){
        alert('click');
      }
      but.addEventListener('click',sayName,false)
      but.removeEventListener('click',sayName,false);
    </script>

|注:参数中的false表示在事件冒泡阶段进行事件处理,嗯,我们也希望它这么做。|
4. IE:

      <button id="but" type="button" name="button">click</button>
    <script type="text/javascript">
      var but=document.getElementById('but');
      function sayName(event){
        alert('click');
      }
      but.attachEvent('onclick',sayName);
      but.detachEvent('onclick',sayName);
    </script>
  1. 区别:
    • 事件处理函数中 this的指向不同;
    • DOM0级较DOM2级可以对同一元素的任意事件绑定处理程序,DOM0级也可以绑定,但是只执行最后一个处理程序,而DOM2级都处理。

事件对象:

触发DOM上的事件时会产生个事件对象event,包含事件相关信息(具体查API or console.log)。区别就是IE下event对象是window下的一个属性。

性能优化:

事件处理程序确实为我们网站带来了交互,但是大量的事件处理容易导致网站的加载过慢,例如:智能社(注:网站效果做得很棒)。

红包书中解释到:函数是对象,而内存中的对象数量过多就导致性能变差。事先准备事件处理程序DOM访问次数变多,延迟了页面的交互就绪时间。

提升性能方案:
* 事件委托:
例:有个列表,列表的每项都需要添加click事件。事件委托的想法就是给列表项的父级元素添加,通过事件对象获取列表项元素配合事件冒泡思想完成。


    <ul id="father">
      <li id="son1">1</li>
      <li id="son2">2</li>
      <li id="son3">3</li>
    </ul>
    <script type="text/javascript">
      var fa=document.getElementById('father');
      function sayName(event){
        var target=event.target;
        switch (target.id) {
          case 'son1':
            alert('son1');
            break;
            case 'son2':
              alert('son2');
              break;
              case 'son3':
                alert('son3');
                break;          
          default:
              alert('other');

        }
      }
      fa.addEventListener('click',sayName,false);
      fa.removeEventListener(sayName);
    </script>
  • 移除事件处理程序:
    用完记得冲厕所。很多时候我们只是添加了事件处理程序,但是用完后没有移除。(嗯,至少我是这样)。

总结:

就原生语言开发来看,不能提供给我们很多便利,往往我们一上来更愿意上手个框架,例如:提到DOM操作的简洁性我会想到jQuery。有因必有果,所以我更情愿通透原生的条件下学习框架。
最后打个广告:广告

参考:

书籍:见红宝书13章
视频:慕课网

下一次会写篇关于前端路由或者vue-router的源码相关。期待!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值