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;
}
發佈了171 篇原創文章 · 獲贊 44 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章