麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

js原生實現(xiàn)FastClick事件的實例

2019-11-19 18:55:02
字體:
供稿:網(wǎng)友

注明:本人學(xué)習(xí)javascript時間不長,最近一直在做web端的手機網(wǎng)頁和微信應(yīng)用,由于最近有用到類似fastclick的功能,在原來的程序中用touchstart和touchend事件模擬,現(xiàn)在嘗試將其封裝,得到了以下兩種有問題的方案。分享給大家,另求大神指導(dǎo)

在手機端Web app開發(fā)中,click事件的300ms的延遲,會造成響應(yīng)緩慢,尤其在低端機中尤為明顯。而使用touchstart或者touchend事件,會和默認(rèn)的滾輪事件發(fā)生沖突,這也不是我們所期望的。

所以,自己動手,豐衣足食,寫了一個快速點擊事件的原生js代碼(考慮到web app開發(fā)的環(huán)境,我們暫時無需考慮對IE等瀏覽器的兼容)。

實現(xiàn)方法1如下:

function FastClickEvent(handler){  var fastclick = {    handler : handler,    bind : function(query){      var targetList = document.querySelectorAll(query);      for(var i=0,len=targetList.length;i<len;i++)      {        targetList[i].addEventListener('touchstart',handleEvent);        targetList[i].addEventListener('touchend',handleEvent);      }    },    unbind : function(query){      var targetList = document.querySelectorAll(query);      for(var i=0,len=targetList.length;i<len;i++)      {        targetList[i].removeEventListener('touchstart',handleEvent);        targetList[i].removeEventListener('touchend',handleEvent);      }    }    }  var touchX = 0 ,touchY = 0;  function handleEvent(event){    switch(event.type)    {      case 'touchstart':        touchX = event.touches[0].clientX;        touchY = event.touches[0].clientY;        break;      case 'touchend':        var x = event.changedTouches[0].clientX;        var y = event.changedTouches[0].clientY;        if(Math.abs(touchX-x)<5||Math.abs(touchY-y)<5)          fastclick.handler(event);        break;    }  };  return fastclick;};

原理:根據(jù)連續(xù)touchstart和touchend事件發(fā)生時位置的變化,來判斷是否是一次點擊

調(diào)用:用一個handler函數(shù)來注冊一個FastClickEvent事件。然后將注冊好的FastClickEvent事件,通過bind方法,綁定到對應(yīng)的元素上去。如下:

var handler = function(event){  console.log(event.target.id+" fastclicked");}var fastClick = new FastClickEvent(handler);fastClick.bind("div");

這段代碼,我們給所有的div元素注冊了fastclick的handler事件。調(diào)用fastClick.unbind來解除元素的綁定。

但是這段代碼有一個問題,為了讓handleEvent事件能夠訪問到touchX,touchY。我采用了閉包的手法,這意味著每次new一個FastClickEvent事件對象,都要在內(nèi)存中再次注入重復(fù)的handleEvent函數(shù)。至于重復(fù)的touchX,touchY,更是不必多說了。

新手求助:原本是想把handleEvent函數(shù)寫到原型里,但是產(chǎn)生的一個問題是handleEvent(event)的this對象是windows,也就是說,我取不到touchX和touchY以及handler對象,造成訪問錯誤。

有一種比較簡單的解決思路,就是只注冊一個fastClickEvent事件,然后在處理程序中根據(jù)event.target的實際值(即發(fā)生事件的對象上)來決定響應(yīng)的內(nèi)容。

但是,這意味著你必須對所有的fastclick事件都非常熟悉。

用這種方法帶來的好處在于,由于你只有一個handleEvent函數(shù),所以基本來說,在頁面釋放之前,除非是你不想再觸發(fā)fastclick事件,否則無需去解綁任何元素的fastclick事件(即使你解綁了,內(nèi)存中仍然存在該handler函數(shù))。而且,你可以很方便的用bind(query)來添加任何動態(tài)生成的元素的fastclick事件,只要你在handler函數(shù)中已經(jīng)寫好相應(yīng)的處理程序。

如果你想添加多個fastclick事件,而且可能要在多個地方注冊,那么也只要new一個新的FastClickEvent對象,然后綁定到對應(yīng)的元素中去就可以了。

下面,介紹一種使用EventTarget類的方法。首先看一下EventTarget

function EventTarget(){  this.handlers = {};}EventTarget.prototype = {  constructor: EventTarget,  addHandler : function(type,handler){    if(typeof this.handlers[type] == "undefined"){      this.handlers[type]=[];    }    this.handlers[type].push(handler);  },  fire : function(event){    if(!event.target){      event.target = this;    }    if(this.handlers[event.type] instanceof Array){      var handlers = this.handlers[event.type];      for(var i=0,len=handlers.length;i<len;i++){        handlers[i](event);      }    }  },  removeHandler : function(type,handler){    if(this.handlers[type] instanceof Array){      var handlers = this.handlers[type];      for(var i=0,len=handler.length;i<len;i++){        if(handlers[i]==handler){          break;        }      }      handlers.splice(i,1);    }  }}

這個類,是一個用來添加、移除以及實現(xiàn)自定義類的接口。參考《JavaScript高級程序設(shè)計第三版》P616-617

那么,如何把這個類,變成我們的fastclick事件接口呢?

定義一個全局變量,用這個變量來完成所有的fastclick事件注冊、刪除以及添加

var FastClick = function(){  var fastclick = new EventTarget(),     touchX = 0 ,    touchY = 0;  function handleEvent(event){    switch(event.type)    {      case 'touchstart':        touchX = event.touches[0].clientX;        touchY = event.touches[0].clientY;        break;      case 'touchend':        var x = event.changedTouches[0].clientX;        var y = event.changedTouches[0].clientY;        if(Math.abs(touchX-x)<5||Math.abs(touchY-y)<5)          fastclick.fire({type:'fastclick',target:event.target});        break;    }  };  fastclick.bind = function(query)  {    var targetList = document.querySelectorAll(query);    for(var i=0,len=targetList.length;i<len;i++)    {      targetList[i].addEventListener('touchstart',handleEvent);      targetList[i].addEventListener('touchend',handleEvent);    }  }  Fastclick.unbind = function(query){    var targetList = document.querySelectorAll(query);    for(var i=0,len=targetList.length;i<len;i++)    {      targetList[i].removeEventListener('touchstart',handleEvent);      targetList[i].removeEventListener('touchend',handleEvent);    }  }  return fastclick;}();

這個全局變量FastClick可以用來添加任意的fastclick事件。

下面來講講如何調(diào)用。

添加事件函數(shù):

FastClick.addHandler('fastclick',function(event){});

刪除事件函數(shù)://匿名事件無法刪除

FastClick.removeHandler('fastclick',handler);

綁定元素

FastClick.bind("div");

解綁

FastClick.unbind("div");

這個方法,同樣需要我們在handler事件中對event.target做預(yù)判,因為雖然這種方法可以添加多個fastclick事件,但是,事件在執(zhí)行的過程中是按順序一個一個執(zhí)行的,也就是說,可能會執(zhí)行你并不想執(zhí)行的函數(shù)。

帶來的好處在于,可以注冊多個fastclick事件,而且無需再次綁定,就可以執(zhí)行了。
比如說,

FastClick.bind("div");FastClick.addHandler(handler1);FastClick.addHandler(handler2);

那么,當(dāng)快速點擊事件發(fā)生在任一div元素時,就會順序執(zhí)行handler1和handler2。

如果我們調(diào)用removeHandler來刪除handler1或handler2,那么相應(yīng)的函數(shù)就不會再執(zhí)行了。

另外,需要注意的是,在handler函數(shù)中,this對象是FastClick.handlers['fastclick']這個數(shù)組,一般情況下,我們用event.target來獲取發(fā)生事件的對象。

用這種方法,基本克服了上面方法的問題,而且,對這個對象重復(fù)new并沒有多大的意義,除非你不想對event.target做預(yù)判,從而生成一大堆的FaskClick類,但這顯然是不高效的。

新手求助:如何能夠?qū)崿F(xiàn)特定的元素的綁定執(zhí)行的函數(shù),也就是: 能夠調(diào)用FastClick.bind(query,handler);實現(xiàn)對符合query條件的元素添加handler的fastclick事件。

以上就是小編為大家?guī)淼膉s原生實現(xiàn)FastClick事件的實例全部內(nèi)容了,希望大家多多支持武林網(wǎng)~

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 毛片免费视频播放 | 欧美日韩在线视频一区二区 | 色综合一区二区 | av电影在线免费 | 色综合久久99 | 九九视频久久 | 日本不卡二区 | 欧美亚成人 | 国产精品午夜未成人免费观看 | 沉沦的校花奴性郑依婷c到失禁 | 色操网 | 最新一区二区三区 | 欧美巨乳在线观看 | 中文字幕免费在线看 | 91精品观看91久久久久久国产 | 中文字幕亚洲一区二区三区 | 国产一级一片免费播放 | 亚洲αv| 欧美精品色精品一区二区三区 | 亚洲精品成人18久久久久 | 国产精品一区久久久久 | 91国内精品久久久久免费影院 | 日日摸夜夜添夜夜添牛牛 | 国产毛片网 | 国产精品九九久久一区hh | 日本在线播放一区二区三区 | 国产成人高清在线观看 | 视频一区二区三区在线播放 | 欧美雌雄另类xxxxx | 午夜精品久久久久久毛片 | 小视频免费在线观看 | 久久国产免费视频 | 国产精品久久久久久久久久电影 | 国产在线精品91 | 免费一级特黄做受大片 | 在线观看免费污视频 | 亚洲第一页中文字幕 | 高清在线观看av | 最近国产中文字幕 | 人成久久 | 刘亦菲一区二区三区免费看 |