真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何通過fastclick源碼分析徹底解決tap“點(diǎn)透”

這篇文章主要為大家展示了“如何通過fastclick源碼分析徹底解決tap“點(diǎn)透””,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“如何通過fastclick源碼分析徹底解決tap“點(diǎn)透””這篇文章吧。

志丹網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)公司于2013年開始到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。

讀fastclick源碼

尼瑪使用太簡單了,直接一句:

FastClick.attach(document.body);

于是所有的click響應(yīng)速度直接提升,剛剛的!什么input獲取焦點(diǎn)的問題也解決了?。?!尼瑪如果真的可以的話,原來改頁面的同事肯定會(huì)啃了我

一步步來,我們跟進(jìn)去,入口就是attach方法:

FastClick.attach = function(layer) {
'use strict';
return new FastClick(layer);
};

這個(gè)兄弟不過實(shí)例化了下代碼,所以我們還要看我們的構(gòu)造函數(shù):

function FastClick(layer) {
'use strict';
var oldOnClick, self = this;
  this.trackingClick = false;
  this.trackingClickStart = 0;
  this.targetElement = null;
  this.touchStartX = 0;
  this.touchStartY = 0;
  this.lastTouchIdentifier = 0;
  this.touchBoundary = 10;
  this.layer = layer;
  if (!layer || !layer.nodeType) {
   throw new TypeError('Layer must be a document node');
  }
  this.onClick = function() { return FastClick.prototype.onClick.apply(self, arguments); };
  this.onMouse = function() { return FastClick.prototype.onMouse.apply(self, arguments); };
  this.onTouchStart = function() { return FastClick.prototype.onTouchStart.apply(self, arguments); };
  this.onTouchMove = function() { return FastClick.prototype.onTouchMove.apply(self, arguments); };
  this.onTouchEnd = function() { return FastClick.prototype.onTouchEnd.apply(self, arguments); };
  this.onTouchCancel = function() { return FastClick.prototype.onTouchCancel.apply(self, arguments); };
  if (FastClick.notNeeded(layer)) {
   return;
  }
  if (this.deviceIsAndroid) {
   layer.addEventListener('mouseover', this.onMouse, true);
   layer.addEventListener('mousedown', this.onMouse, true);
   layer.addEventListener('mouseup', this.onMouse, true);
  }
  layer.addEventListener('click', this.onClick, true);
  layer.addEventListener('touchstart', this.onTouchStart, false);
  layer.addEventListener('touchmove', this.onTouchMove, false);
  layer.addEventListener('touchend', this.onTouchEnd, false);
  layer.addEventListener('touchcancel', this.onTouchCancel, false);
 
  if (!Event.prototype.stopImmediatePropagation) {
   layer.removeEventListener = function(type, callback, capture) {
    var rmv = Node.prototype.removeEventListener;
    if (type === 'click') {
     rmv.call(layer, type, callback.hijacked || callback, capture);
    } else {
     rmv.call(layer, type, callback, capture);
    }
   };
 
   layer.addEventListener = function(type, callback, capture) {
    var adv = Node.prototype.addEventListener;
    if (type === 'click') {
     adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
      if (!event.propagationStopped) {
       callback(event);
      }
     }), capture);
    } else {
     adv.call(layer, type, callback, capture);
    }
   };
  }
  if (typeof layer.onclick === 'function') {
   oldOnClick = layer.onclick;
   layer.addEventListener('click', function(event) {
 oldOnClick(event);
 }, false);
 layer.onclick = null;
}
}

看看這段代碼,上面很多屬性干了什么事情我也不知道......于是忽略了

if (!layer || !layer.nodeType) {
throw new TypeError('Layer must be a document node');
}

其中這里要注意,我們必須傳入一個(gè)節(jié)點(diǎn)給構(gòu)造函數(shù),否則會(huì)出問題

然后這個(gè)家伙將一些基本的鼠標(biāo)事件注冊在自己的屬性方法上了,具體是干神馬的我們后面再說

在后面點(diǎn)有個(gè)notNeeded方法:

 FastClick.notNeeded = function(layer) {
  'use strict';
  var metaViewport;
  if (typeof window.ontouchstart === 'undefined') {
   return true;
  }
  if ((/Chrome\/[0-9]+/).test(navigator.userAgent)) {
   if (FastClick.prototype.deviceIsAndroid) {
    metaViewport = document.querySelector('meta[name=viewport]');
    if (metaViewport && metaViewport.content.indexOf('user-scalable=no') !== -1) {
     return true;
    }
   } else {
    return true;
   }
  }
  if (layer.style.msTouchAction === 'none') {
   return true;
  }
  return false;
 };

這個(gè)方法用于判斷是否需要用到fastclick,注釋的意思不太明白,我們看看代碼吧

首先一句:

if (typeof window.ontouchstart === 'undefined') {
 return true;
}

如果不支持touchstart事件的話,返回true
PS:現(xiàn)在的只管感受就是fastclick應(yīng)該也是以touch事件模擬的,但是其沒有點(diǎn)透問題

后面還判斷了android的一些問題,我這里就不關(guān)注了,意思應(yīng)該就是支持touch才能支持吧,于是回到主干代碼

主干代碼中,我們看到,如果瀏覽器不支持touch事件或者其它問題就直接跳出了

然后里面有個(gè)deviceIsAndroid的屬性,我們跟去看看(其實(shí)不用看也知道是判斷是否是android設(shè)備)

FastClick.prototype.deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0;

綁定事件

好了,這家伙開始綁定注冊事件了,至此還未看出異樣

 if (this.deviceIsAndroid) {
  layer.addEventListener('mouseover', this.onMouse, true);
  layer.addEventListener('mousedown', this.onMouse, true);
  layer.addEventListener('mouseup', this.onMouse, true);
 }
 layer.addEventListener('click', this.onClick, true);
 layer.addEventListener('touchstart', this.onTouchStart, false);
 layer.addEventListener('touchmove', this.onTouchMove, false);
 layer.addEventListener('touchend', this.onTouchEnd, false);
 layer.addEventListener('touchcancel', this.onTouchCancel, false);

具體的事件函數(shù)在前面被重寫了,我們暫時(shí)不管他,繼續(xù)往后面看先(話說,這家伙綁定的事件夠多的)

stopImmediatePropagation

完了多了一個(gè)屬性:

阻止當(dāng)前事件的冒泡行為并且阻止當(dāng)前事件所在元素上的所有相同類型事件的事件處理函數(shù)的繼續(xù)執(zhí)行.

如果某個(gè)元素有多個(gè)相同類型事件的事件監(jiān)聽函數(shù),則當(dāng)該類型的事件觸發(fā)時(shí),多個(gè)事件監(jiān)聽函數(shù)將按照順序依次執(zhí)行.如果某個(gè)監(jiān)聽函數(shù)執(zhí)行了 event.stopImmediatePropagation()方法,則除了該事件的冒泡行為被阻止之外(event.stopPropagation方法的作用),該元素綁定的其余相同類型事件的監(jiān)聽函數(shù)的執(zhí)行也將被阻止.

 
     
         
     
     
         
             

paragraph

         
                 
 if (!Event.prototype.stopImmediatePropagation) {
  layer.removeEventListener = function(type, callback, capture) {
   var rmv = Node.prototype.removeEventListener;
   if (type === 'click') {
    rmv.call(layer, type, callback.hijacked || callback, capture);
   } else {
    rmv.call(layer, type, callback, capture);
   }
  };
 
  layer.addEventListener = function(type, callback, capture) {
   var adv = Node.prototype.addEventListener;
   if (type === 'click') {
    adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
     if (!event.propagationStopped) {
      callback(event);
     }
    }), capture);
   } else {
    adv.call(layer, type, callback, capture);
   }
  };
 }

然后這家伙重新定義了下注冊與注銷事件的方法,

我們先看注冊事件,其中用到了Node的addEventListener,這個(gè)Node是個(gè)什么呢?

由此觀之,Node是一個(gè)系統(tǒng)屬性,代表我們的節(jié)點(diǎn)吧,所以這里重寫了注銷的事件

這里,我們發(fā)現(xiàn),其實(shí)他只對click進(jìn)行了特殊處理

adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
if (!event.propagationStopped) {
 callback(event);
}
}), capture);

其中有個(gè)hijacked劫持是干神馬的就暫時(shí)不知道了,估計(jì)是在中間是否改寫的意思吧
然后這里重寫寫了下,hijacked估計(jì)是一個(gè)方法,就是為了阻止在一個(gè)dom上注冊多次事件多次執(zhí)行的情況而存在的吧

注銷和注冊差不多我們就不管了,到此我們其實(shí)重寫了我們傳入dom的注冊注銷事件了,好像很厲害的樣子,意思以后這個(gè)dom調(diào)用click事件用的是我們的,當(dāng)然這只是我暫時(shí)的判斷,具體還要往下讀,而且我覺得現(xiàn)在的判斷不靠譜,于是我們繼續(xù)吧

我們注銷事件時(shí)候可以用addEventListener 或者 dom.onclick=function(){},所以這里有了下面的代碼:

if (typeof layer.onclick === 'function') {
 oldOnClick = layer.onclick;
 layer.addEventListener('click', function(event) {
 oldOnClick(event);
 }, false);
 layer.onclick = null;
}

此處,他的主干流程居然就完了,意思是他所有的邏輯就在這里了,不論入口還是出口應(yīng)該就是事件注冊了,于是我們寫個(gè)代碼來看看

測試入口

 
 

 $('#addEvent').click(function () {
     var dom = $('#addEvent1')[0]
     dom.addEventListener('click', function () {
         alert('')
         var s = '';
     })
 });

我們來這個(gè)斷點(diǎn)看看我們點(diǎn)擊后干了什么,我們現(xiàn)在點(diǎn)擊按鈕1會(huì)為按鈕2注冊事件:

但是很遺憾,我們在電腦上不能測試,所以增加了我們讀代碼的困難,在手機(jī)上測試后,發(fā)現(xiàn)按鈕2響應(yīng)很快,但是這里有點(diǎn)看不出問題

最后alert了一個(gè)!Event.prototype.stopImmediatePropagation發(fā)現(xiàn)手機(jī)和電腦都是false,所以我們上面搞的東西暫時(shí)無用

 FastClick.prototype.onClick = function (event) {
     'use strict';
     var permitted;
     alert('終于尼瑪進(jìn)來了');
     if (this.trackingClick) {
         this.targetElement = null;
         this.trackingClick = false;
         return true;
     }
     if (event.target.type === 'submit' && event.detail === 0) {
         return true;
     }
     permitted = this.onMouse(event);
     if (!permitted) {
         this.targetElement = null;
     }
     return permitted;
 };

然后我們終于進(jìn)來了,現(xiàn)在我們需要知道什么是trackingClick 了

/**
* Whether a click is currently being tracked.
* @type Boolean
*/
this.trackingClick = false;

我們最初這個(gè)屬性是false,但是到這里就設(shè)置為true了,就直接退出了,說明綁定事件終止,算了這個(gè)我們暫時(shí)不關(guān)注,我們干點(diǎn)其它的,

因?yàn)?,我覺得重點(diǎn)還是應(yīng)該在touch事件上

PS:到這里,我們發(fā)現(xiàn)這個(gè)庫應(yīng)該不只是將click加快,而是所有的響應(yīng)都加快了

我在各個(gè)事件部分log出來東西,發(fā)現(xiàn)有click的地方都只執(zhí)行了touchstart與touchend,于是至此,我覺得我的觀點(diǎn)成立
他使用touch事件模擬量click,于是我們就只跟進(jìn)這一塊就好:

 FastClick.prototype.onTouchStart = function (event) {
     'use strict';
     var targetElement, touch, selection;
     log('touchstart');
     if (event.targetTouches.length > 1) {
         return true;
     }
     targetElement = this.getTargetElementFromEventTarget(event.target);
     touch = event.targetTouches[0];
     if (this.deviceIsIOS) {
         selection = window.getSelection();
         if (selection.rangeCount && !selection.isCollapsed) {
             return true;
         }
         if (!this.deviceIsIOS4) {
             if (touch.identifier === this.lastTouchIdentifier) {
                 event.preventDefault();
                 return false;
             }
             this.lastTouchIdentifier = touch.identifier;
             this.updateScrollParent(targetElement);
         }
     }
     this.trackingClick = true;
     this.trackingClickStart = event.timeStamp;
     this.targetElement = targetElement;
     this.touchStartX = touch.pageX;
     this.touchStartY = touch.pageY;
     if ((event.timeStamp - this.lastClickTime) < 200) {
         event.preventDefault();
     }
     return true;
 };

其中用到了一個(gè)方法:

FastClick.prototype.getTargetElementFromEventTarget = function (eventTarget) {
  'use strict';
  if (eventTarget.nodeType === Node.TEXT_NODE) {
    return eventTarget.parentNode;
  }
  return eventTarget;
};

他是獲取我們當(dāng)前touchstart的元素

然后將鼠標(biāo)的信息記錄了下來,他記錄鼠標(biāo)信息主要在后面touchend時(shí)候根據(jù)x、y判斷是否為click
是ios情況下還搞了一些事情,我這里跳過去了

然后這里記錄了一些事情就跳出去了,沒有特別的事情,現(xiàn)在我們進(jìn)入我們的出口touchend

 FastClick.prototype.onTouchEnd = function (event) {
     'use strict';
     var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
     log('touchend');
     if (!this.trackingClick) {
         return true;
     }
     if ((event.timeStamp - this.lastClickTime) < 200) {
         this.cancelNextClick = true;
         return true;
     }
     this.lastClickTime = event.timeStamp;
     trackingClickStart = this.trackingClickStart;
     this.trackingClick = false;
     this.trackingClickStart = 0;
     if (this.deviceIsIOSWithBadTarget) {
         touch = event.changedTouches[0];
         targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
         targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
     }
     targetTagName = targetElement.tagName.toLowerCase();
     if (targetTagName === 'label') {
         forElement = this.findControl(targetElement);
         if (forElement) {
             this.focus(targetElement);
             if (this.deviceIsAndroid) {
                 return false;
             }
             targetElement = forElement;
         }
     } else if (this.needsFocus(targetElement)) {
         if ((event.timeStamp - trackingClickStart) > 100 || (this.deviceIsIOS && window.top !== window && targetTagName === 'input')) {
             this.targetElement = null;
             return false;
         }
         this.focus(targetElement);
         if (!this.deviceIsIOS4 || targetTagName !== 'select') {
             this.targetElement = null;
             event.preventDefault();
         }
         return false;
     }
     if (this.deviceIsIOS && !this.deviceIsIOS4) {
         scrollParent = targetElement.fastClickScrollParent;
         if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
             return true;
         }
     }
     if (!this.needsClick(targetElement)) {
         event.preventDefault();
         this.sendClick(targetElement, event);
     }
     return false;
 };

這個(gè)家伙洋洋灑灑干了許多事情

這里糾正一個(gè)錯(cuò)誤,他onclick那些東西現(xiàn)在也執(zhí)行了......可能是我屏幕有變化(滑動(dòng))導(dǎo)致

if ((event.timeStamp - this.lastClickTime) < 200) {
 this.cancelNextClick = true;
 return true;
}

這個(gè)代碼很關(guān)鍵,我們首次點(diǎn)擊會(huì)執(zhí)行下面的邏輯,如果連續(xù)點(diǎn)擊就直接完蛋,下面的邏輯丫的不執(zhí)行了......
這個(gè)不執(zhí)行了,那么這個(gè)勞什子又干了什么事情呢?
事實(shí)上下面就沒邏輯了,意思是如果確實(shí)點(diǎn)擊過快,兩次點(diǎn)擊只會(huì)執(zhí)行一次,這個(gè)閥值為200ms,這個(gè)暫時(shí)看來是沒有問題的

好了,我們繼續(xù)往下走,于是我意識(shí)到又到了一個(gè)關(guān)鍵點(diǎn)
因?yàn)槲覀冇胻ap事件不能使input獲得焦點(diǎn),但是fastclick卻能獲得焦點(diǎn),這里也許是一個(gè)關(guān)鍵,我們來看看幾個(gè)與獲取焦點(diǎn)有關(guān)的函數(shù)

 FastClick.prototype.focus = function (targetElement) {
     'use strict';
     var length;
     if (this.deviceIsIOS && targetElement.setSelectionRange) {
         length = targetElement.value.length;
         targetElement.setSelectionRange(length, length);
     } else {
         targetElement.focus();
     }
 };

setSelectionRange是我們的關(guān)鍵,也許他是這樣獲取焦點(diǎn)的......具體我還要下來測試,留待下次處理吧
然后下面如果時(shí)間間隔過長,代碼就不認(rèn)為操作的是同一dom結(jié)構(gòu)了

最后迎來了本次的關(guān)鍵:sendClick,無論是touchend還是onMouse都會(huì)匯聚到這里

 FastClick.prototype.sendClick = function (targetElement, event) {
     'use strict';
     var clickEvent, touch;
     // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
     if (document.activeElement && document.activeElement !== targetElement) {
         document.activeElement.blur();
     }
     touch = event.changedTouches[0];
     // Synthesise a click event, with an extra attribute so it can be tracked
     clickEvent = document.createEvent('MouseEvents');
     clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
     clickEvent.forwardedTouchEvent = true;
     targetElement.dispatchEvent(clickEvent);
 };

他創(chuàng)建了一個(gè)鼠標(biāo)事件,然后dispatchEvent事件(這個(gè)與fireEvent類似)

 //document上綁定自定義事件ondataavailable
 document.addEventListener('ondataavailable', function (event) {
 alert(event.eventType);
 }, false);
 var obj = document.getElementById("obj");
 //obj元素上綁定click事件
 obj.addEventListener('click', function (event) {
 alert(event.eventType);
 }, false);
 //調(diào)用document對象的 createEvent 方法得到一個(gè)event的對象實(shí)例。
 var event = document.createEvent('HTMLEvents');
 // initEvent接受3個(gè)參數(shù):
 // 事件類型,是否冒泡,是否阻止瀏覽器的默認(rèn)行為
 event.initEvent("ondataavailable", true, true);
 event.eventType = 'message';
 //觸發(fā)document上綁定的自定義事件ondataavailable
 document.dispatchEvent(event);

 var event1 = document.createEvent('HTMLEvents');
 event1.initEvent("click", true, true);
 event1.eventType = 'message';
 //觸發(fā)obj元素上綁定click事件
 document.getElementById("test").onclick = function () {
 obj.dispatchEvent(event1);
 };

至此,我們就知道了,我們?yōu)閐om先綁定了鼠標(biāo)事件,然后touchend時(shí)候觸發(fā)了,而至于為什么本身注冊的click未觸發(fā)就要回到上面代碼了

解決“點(diǎn)透”(成果)

有了這個(gè)思路,我們來試試我們抽象出來的代碼:

 
 
 
     
     
     
 
 
     
     
     
         
                       
     
               var el = null;          function getEvent(el, e, type) {              e = e.changedTouches[0];              var event = document.createEvent('MouseEvents');              event.initMouseEvent(type, true, true, window, 1, e.screenX, e.screenY, e.clientX, e.clientY, false, false, false, false, 0, null);              event.forwardedTouchEvent = true;              return event;          }          list.addEventListener('touchstart', function (e) {              var firstTouch = e.touches[0]              el = firstTouch.target;              t1 = e.timeStamp;          })          list.addEventListener('touchend', function (e) {              e.preventDefault();              var event = getEvent(el, e, 'click');              el.dispatchEvent(event);          })          var list = document.getElementById('list');          list.addEventListener('click', function (e) {              list.style.display = 'none';              setTimeout(function () {                  list.style.display = '';              }, 1000);          })          

這樣的話,便不會(huì)點(diǎn)透了,這是因?yàn)閦epto touch事件全部綁定值document,所以 e.preventDefault();無用
結(jié)果我們這里是直接在dom上,e.preventDefault();
便起了作用不會(huì)觸發(fā)瀏覽器默認(rèn)事件,所以也不存在點(diǎn)透問題了,至此點(diǎn)透事件告一段落......

幫助理解的圖

代碼在公司寫的,回家后不知道圖上哪里了,各位將就看吧

如何通過fastclick源碼分析徹底解決tap“點(diǎn)透”

如何通過fastclick源碼分析徹底解決tap“點(diǎn)透”

如何通過fastclick源碼分析徹底解決tap“點(diǎn)透”

如何通過fastclick源碼分析徹底解決tap“點(diǎn)透”

如何通過fastclick源碼分析徹底解決tap“點(diǎn)透”

為什么zepto會(huì)點(diǎn)透/fastclick如何解決點(diǎn)透

我最開始就給老大說zepto處理tap事件不夠好,搞了很多事情出來

因?yàn)樗录墙壎ǖ絛ocument上,先touchstart然后touchend,根據(jù)touchstart的event參數(shù)判斷該dom是否注冊了tap事件,有就觸發(fā)

于是問題來了,zepto的touchend這里有個(gè)event參數(shù),我們event.preventDefault(),這里本來都是最上層了,這就代碼壓根沒什么用

但是fastclick處理辦法不可謂不巧妙,這個(gè)庫直接在touchend的時(shí)候就觸發(fā)了dom上的click事件而替換了本來的觸發(fā)時(shí)間

意思是原來要350-400ms執(zhí)行的代碼突然就移到了50-100ms,然后這里雖然使用了touch事件但是touch事件是綁定到了具體dom而不是document上

所以e.preventDefault是有效的,我們可以阻止冒泡,也可以阻止瀏覽器默認(rèn)事件,這個(gè)才是fastclick的精華部分,不可謂不高?。。?!

整個(gè)fastclick代碼讀來醍醐灌頂,今天收獲很大,在此記錄

后記

上面的說法有點(diǎn)問題,這修正一下:

首先,我們回到原來的zepto方案,看看他有什么問題:

因?yàn)閖s標(biāo)準(zhǔn)本不支持tap事件,所以zepto tap是touchstart與touchend模擬而出  zepto在初始化時(shí)便給document綁定touch事件,在我們點(diǎn)擊時(shí)根據(jù)event參數(shù)獲得當(dāng)前元素,并會(huì)保存點(diǎn)下和離開時(shí)候的鼠標(biāo)位置  根據(jù)當(dāng)前元素鼠標(biāo)移動(dòng)范圍判斷是否為類點(diǎn)擊事件,如果是便觸發(fā)已經(jīng)注冊好的tap事件

然后fastclick處理比較與zepto基本一致,但是又有所不同

fastclick是將事件綁定到你傳的元素(一般是document.body)

② 在touchstart和touchend后(會(huì)手動(dòng)獲取當(dāng)前點(diǎn)擊el),如果是類click事件便手動(dòng)觸發(fā)了dom元素的click事件

所以click事件在touchend便被觸發(fā),整個(gè)響應(yīng)速度就起來了,觸發(fā)實(shí)際與zepto tap一樣

好了,為什么基本相同的代碼,zepto會(huì)點(diǎn)透而fastclick不會(huì)呢?

原因是zepto的代碼里面有個(gè)settimeout,而就算在這個(gè)代碼里面執(zhí)行e.preventDefault()也不會(huì)有用

這就是根本區(qū)別,因?yàn)閟ettimeout會(huì)將優(yōu)先級較低

有了定期器,當(dāng)代碼執(zhí)行到setTimeout的時(shí)候, 就會(huì)把這個(gè)代碼放到JS的引擎的最后面 

而我們代碼會(huì)馬上檢測到e.preventDefault,一旦加入settimeout,e.preventDefault便不會(huì)生效,這是zepto點(diǎn)透的根本原因

以上是“如何通過fastclick源碼分析徹底解決tap“點(diǎn)透””這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


當(dāng)前標(biāo)題:如何通過fastclick源碼分析徹底解決tap“點(diǎn)透”
本文網(wǎng)址:http://weahome.cn/article/psihoi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部