js中一系列的兼容---惰性载入优化

惰性载入函数

为了避免每次都判断浏览器能力,影响效率,将判断放在返回的函数外面。(惰性载入)

惰性载入函数表示函数执行的分支仅会发生一次。

有两种实现惰性载入的方式:

  • 第一种是在函数第一次被调用时在处理函数。在第一次调用的过程中,该函数会被覆盖为另外一个按合适的方式执行的函数,这样任何对原函数的调用都不会再经过执行的分支了。
  • 第二种是在声明函数时就指定适当的函数。第一次调用函数时就不会损失性能了,而在代码首次加载时会损失一点性能。

其实,惰性载入是js设计模式之一,即惰性模式。啊,原来,还有这么个高大上的名字。js设计模式中有很多平时很常见,但是不知道名字的模式。在下面的学习中,我将不断总结。

注:下文中,我使用事件注册样式获取做了两个例子。你可以学习到如何写惰性载入函数,其他兼容的方法也就不在话下了。

事件注册兼容

/* 为了避免每次都判断浏览器能力,影响效率,将判断放在返回的函数外面(惰性载入)*/
    /*addEventListener -- IE9以上
      attachEvent -- IE9(不包括IE9)支持,冒泡阶段才会被调用
        1. 三种注册事件,回调函数中this指向不一样
            使用addEventListener注册的事件,回调函数中this指向target
            使用attachEvent注册的事件,回调函数中this指向window
         2. 三种注册事件中,回调函数接收事件对象方式不一样
            在ie下,事件对象是在全局的,也就 window下,做为window的一个属性
            在其他浏览器,都做为方法的第一个参数传入,所以这样写是为了兼容
        例:window.onload =function () {
            var div = document.getElementById("dvd1");

            function huidiao(e){
                console.log(e+"就是当前的事件对象")
                console.log( this+ "就是当前你点击的对象");
                alert("我是div的点击事件,所有浏览器中,我的功能都是弹出来这句话!");
            }
            //通用的
            div.onclick = huidiao;

            //ie9以上才支持
            div.addEventListener("click",huidiao)

            //ie9(不包括9)以下支持的
            div.attachEvent("onclick",function(){
                huidiao.call(div, window.event);
            })
        }
        所以要统一设置回调函数中this指向target,事件对象方式一致
    */

事件兼容+惰性载入思想实现:

 //方法二:声明函数时就指定适当的函数
  var registerEvent = (function(){
     if (window.addEventListener) {
      return function(target, type, handler) {
        console.log(this); //this指向window
        target.addEventListener(type, handler, false);
      }
    } else if (window.attachEvent) {
      return function(target, type, handler) {
        target.attachEvent("on" + type, function() {
          handler.call(target, window.event);
        });
      }
    } else {
      return function(target, type, handler) {
        target["on" + type] = handler;
      }
    }
  })();

//方法一:第一次调用函数时,该函数覆盖为另一个更为合适执行的函数
function registerEvent(target, type, handler) {
    if (window.addEventListener) {
        console.log("------");
      registerEvent =  function(target, type, handler) {
        console.log(this); //this指向window
        console.log(target);
        target.addEventListener(type, handler, false);
      }
    } else if (window.attachEvent) {
      registerEvent = function(target, type, handler) {
        target.attachEvent("on" + type, function() {
          handler.call(target, window.event);
        });
      }
    } else {
      registerEvent = function(target, type, handler) {
        target["on" + type] = handler;
      }
    }
    return registerEvent(target, type, handler);
  }

//测试代码
  var div1 = document.getElementById("div1");
  console.log(div1);

  registerEvent(div1, "click", function(e) {
    console.log(e + "就是当前的事件对象");
    console.log(e.type);
    console.log(this + "就是当前你点击的对象");
    console.log(this.innerHTML);
    alert("我是div的点击事件,所有浏览器中,我的功能都是弹出来这句话!");
  });

   registerEvent(div1, "click", function(e) {
    alert("2");
  });

获取元素样式+惰性载入兼容写法

function getStyle(elem,property){
        return window.getComputedStyle?window.getComputedStyle(elem,null).getPropertyValue(property):elem.currentStyle.getAttribute(property);
    }

改革版:

//方法一:第一次调用函数时,该函数覆盖为另一个更为合适执行的函数
function getStyle(obj,propertyName){
    if(window.getComputedStyle){
        getStyle = function(obj,propertyName){
            return window.getComputedStyle(obj,null).getPropertyValue(propertyName);
        }
    }else{
        getStyle = function(obj,propertyName){
            return obj.currentStyle.getAttribute(propertyName);
            }
        }
        return getStyle(obj,propertyName);
   }
   //方法二:声明函数时就指定适当的函数(立即执行函数)
   var getStyle = (function(){
    if(window.getComputedStyle){
        return function(obj,propertyName){
            return window.getComputedStyle(obj,null).getPropertyValue(propertyName);
        }
    }else{
        return function(obj,propertyName){
            return obj.currentStyle.getAttribute(propertyName);
        }
    }
   })();

//测试代码:
//html:  <div id="div1" style="width:100px; background-color:red" >123</div>
 var div1 = document.getElementById("div1");

 console.log(getStyle(div1,'width'));
 console.log(getStyle(div1,'background-color'));

transform兼容写法

问题引入:
要想让元素动起来,修改元素的left,top值,但会引起页面重绘,而transform不会,所以要优先使用transform。

function getTransform() {
        var transform = '',
            divStyle = document.createElement('div').style,
            transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'oTransform'];

         //通过循环找出浏览器识别的那个,in操作符用于判断是否识别
        for (var i = 0,len = transformArr.length; i < len; i++) {
            if (transformArr[i] in divStyle) {
                return transform = transformArr[i];
            }
        }
        return transform;
    }
    console.log(getTransform());

该方法用于获取浏览器支持的transform属性。如果返回的是空字符串,则表示当前浏览器并不支持transform,此时需要使用left,top值改变元素位置。如果支持,就改变transform值。

判断是否选择了内容

var txt;
if(window.getSelection){
    txt = window.getSelection().toString();
}else{
    txt = document.selection.createRange().text;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值