zoukankan      html  css  js  c++  java
  • 利用on和off方法编写高效的js代码

      先说下将这个话题的起因:最近发现公司的功能代码,很多在dom对象删除以后,其声明的绑定在window上的resize事件还一直存在,导致相同的功能代码执行了几次。对于我这种轻微代码洁癖的人来说,简直是个大坑。

      所以,这里以jQuery的resize方法为例,讲解下我所理解的高效写法。

      先看一下普通的在window下绑定resize事件:

    1 $(window).resize(function(){
    2     console.log("hehe");
    3 });
    4 $(window).resize(function(){
    5     console.log("hehe2");
    6 });

      触发了几次resize后的执行结果如下:

      两个事件处理程序不会互相覆盖是因为,jQuery的方法都是DOM2级的(这里就不细说了)。而问题就出在这里,如果再删除DOM对象后,其特有的、非绑定在本身的响应方法没有对应删除的话,会一直积累下来,像幽灵一般。而这里就是所谓的影响性能,让浏览器宝贵的CPU被无效的功能代码消耗掉,用户体验也在积累一定数量级该幽灵代码后,逐级降低,甚至卡死。

      怎么解决呢?当然是kill掉!

      如果用unbind方法,是可以进行清除操作,但是关键有时候会勿删,特别是多人协作的团队。所以,on和off方法就派上用场了!

      将resize方法改造一下:

    1 $(window).on("resize.fn1", function(){
    2     console.log("hehe");
    3 });
    4 $(window).on("resize.fn2", function(){
    5     console.log("hehe2");
    6 });

      重点是on方法的第一个参数:resize.fn1。实心点之前,是该window对象要绑定的resize方法;实心点之后是为该方法取的一个别名,用于标识该方法(注意不能有空格,这是我的一位同事遇到的)。

      这个别名,是用于调用off方法时,删除指定对应的处理程序。

      如我要删除输出“hehe”的处理程序,代码如下:  

    1 $(window).off("resize.fn1");

      这样,就可以把不需要的功能代码精确销毁,而不会导致勿删。

      另外提醒下,resize事件可以根据需要写n个,然后,你可以根据业务的功能划分,为相同生存期的代码标识相同的别名,以便可以统一销毁。

      扩展一下思路:

      一般我们写扩展性比较好的函数,比如生成一个遮罩,一般都会预留一个calbackl方法,如下:

     1 function overlay(options){
     2   var default = {
     3   /*其他参数 */
     4   callback:false                  
     5     };  
     6   var settings = $.extend({}, default, options);
     7   if(!!settings.callback){
     8     settings.callback();           
     9     }    
    10 }

      但是,我们可以把扩展性做得更好,比如当遮罩初始化生成时,在window上绑定一个resize事件,输出1

     1 var data = {
     2     /*其他参数*/
     3     extFn : [{
     4                obj:$(window), 
     5                name:"resize.overlay", 
     6                fn:function(){
     7                      console.log(1);
     8                 }
     9                }]
    10 };
    11 
    12 overlay(data);
    13 
    14 function overlay(options){
    15   var default = {
    16     /*其他参数*/  
    17     callback:false,
    18     extFn:[]    
    19   };  
    20   var settings = $.extend({}, default, options);
    21 
    22   if(settins.extFn.length > 0){
    23     var extFn_obj, extFn_name, extFn_fn;
    24   
    25     for(var i = 0, len = settings.extFn.length; i < len; i++){
    26         extFn_obj = settings.extFn[i].obj;
    27         extFn_name = settings.extFn[i].name;
    28         extFn_fn = settings.extFn[i].fn;
    29         extFn_obj.off(extFn_name);//销毁旧的事件绑定
    30         extFn_obj.on(extFn_name, extFn_fn);//添加新的事件绑定
    31     }  
    32   }  
    33   
    34   /*其他方法及callback*/  
    35 }

      当然,在销毁生成遮罩时,也应对应的销毁自定义绑定的扩展方法,这里就不叨叨了~

      via:cnblogs.com/walls/p/4253663.html


    喜欢我文章的朋友,可以通过以下方式关注我:

    wall的个人博客
  • 相关阅读:
    js 隐藏、显示html 标签内容
    Elasticsearch第二章:Elasticsearch6.4.2破解xpack白金认证,以及kibana登录
    Elasticsearch第一章: 安装elasticsearch和kibana
    spring springboot2 结合 websocket+sockJs+stomp 实现个人订阅和广播模式
    MongoDB 查询重复手机号数量
    esxi直通sata控制器给群辉。群辉无法识别全部盘符,无法读取smart
    esxi直通显卡之后 游戏无法打开
    esxi硬盘直通,RDM
    SpringSecurity整合SpringSession-Redis 限制用户登录,SpringSecurity单用户登录
    Spring Security流程解释与配置
  • 原文地址:https://www.cnblogs.com/walls/p/4253663.html
Copyright © 2011-2022 走看看