日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FastClick 填坑及源码解析

發(fā)布時(shí)間:2024/1/1 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FastClick 填坑及源码解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近產(chǎn)品妹子提出了一個(gè)體驗(yàn)issue —— 用 iOS 在手Q閱讀書友交流區(qū)發(fā)表書評(píng)時(shí),光標(biāo)點(diǎn)擊總是不好定位到正確的位置:

如上圖,具體表現(xiàn)是較快點(diǎn)擊時(shí),光標(biāo)總會(huì)跳到 textarea 內(nèi)容的尾部。只有當(dāng)點(diǎn)擊停留時(shí)間較久一點(diǎn)(比如超過150ms)才能把光標(biāo)正常定位到正確的位置。

一開始我以為是 iOS 原生的交互問題沒太在意,但后來發(fā)現(xiàn)訪問某些頁面又是沒有這種奇怪體驗(yàn)的。

然后懷疑是否 JS 注冊(cè)了某些事件導(dǎo)致的問題,于是試著把業(yè)務(wù)模塊移除了再跑一遍,發(fā)現(xiàn)問題照舊。

于是只好繼續(xù)做排除法,把頁面上的一些庫一點(diǎn)點(diǎn)移掉再運(yùn)行頁面,結(jié)果發(fā)現(xiàn)搗亂的小鬼果然是嫌疑最大的 Fastclick。

然后呢,我試著按API所說,給 textarea 加上一個(gè)名為“needsclick”的類名,希望能繞過 fastclick 的處理直接走原生點(diǎn)擊事件,結(jié)果訝異地發(fā)現(xiàn)屁用沒有。。。

對(duì)此感謝后面我們小組的 kindeng 童鞋幫忙研究了下并提供了解決方案,不過我還想進(jìn)一步研究到底是什么原因?qū)е铝诉@個(gè)坑、Fastclick 對(duì)我的頁面做了神馬~

所以昨晚花了點(diǎn)時(shí)間一口氣把源碼都蹂躪了一遍。

這會(huì)是一篇很長(zhǎng)的文章,但會(huì)是注釋非常詳盡的剖析文。

文章帶分析的源碼我也掛在我的 github 倉庫上了,有興趣的童鞋可以去下載來看。

閑話不多說,咱們開始深入 FastClick?源碼陣營(yíng)。

我們知道,注冊(cè)一個(gè) FastClick?事件非常簡(jiǎn)單,它是這樣的:

if ('addEventListener' in document) {document.addEventListener('DOMContentLoaded', function() {var fc = FastClick.attach(document.body); //生成實(shí)例}, false); }

所以我們從這里著手,打開源碼看下 FastClick .attach 方法:

FastClick.attach = function(layer, options) {return new FastClick(layer, options);};

這里返回了一個(gè)?FastClick 實(shí)例,所以咱們拉到前面看看?FastClick 構(gòu)造函數(shù):

function FastClick(layer, options) {var oldOnClick;options = options || {};//定義了一些參數(shù)...//如果是屬于不需要處理的元素類型,則直接返回if (FastClick.notNeeded(layer)) {return;}//語法糖,兼容一些用不了 Function.prototype.bind 的舊安卓//所以后面不走 layer.addEventListener('click', this.onClick.bind(this), true);function bind(method, context) {return function() { return method.apply(context, arguments); };}var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];var context = this;for (var i = 0, l = methods.length; i < l; i++) {context[methods[i]] = bind(context[methods[i]], context);}//安卓則做額外處理if (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);// 兼容不支持 stopImmediatePropagation 的瀏覽器(比如 Android 2)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') {//留意這里 callback.hijacked 中會(huì)判斷 event.propagationStopped 是否為真來確保(安卓的onMouse事件)只執(zhí)行一次//在 onMouse 事件里會(huì)給 event.propagationStopped 賦值 trueadv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {if (!event.propagationStopped) {callback(event);}}), capture);} else {adv.call(layer, type, callback, capture);}};}// 如果layer直接在DOM上寫了 onclick 方法,那我們需要把它替換為 addEventListener 綁定形式if (typeof layer.onclick === 'function') {oldOnClick = layer.onclick;layer.addEventListener('click', function(event) {oldOnClick(event);}, false);layer.onclick = null;}}

在初始通過?FastClick.notNeeded 方法判斷是否需要做后續(xù)的相關(guān)處理:

//如果是屬于不需要處理的元素類型,則直接返回if (FastClick.notNeeded(layer)) {return;}

我們看下這個(gè)?FastClick.notNeeded 都做了哪些判斷:

//是否沒必要使用到 Fastclick 的檢測(cè)FastClick.notNeeded = function(layer) {var metaViewport;var chromeVersion;var blackberryVersion;var firefoxVersion;// 不支持觸摸的設(shè)備if (typeof window.ontouchstart === 'undefined') {return true;}// 獲取Chrome版本號(hào),若非Chrome則返回0chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];if (chromeVersion) {if (deviceIsAndroid) { //安卓metaViewport = document.querySelector('meta[name=viewport]');if (metaViewport) {// 安卓下,帶有 user-scalable="no" 的 meta 標(biāo)簽的 chrome 是會(huì)自動(dòng)禁用 300ms 延遲的,所以無需 Fastclickif (metaViewport.content.indexOf('user-scalable=no') !== -1) {return true;}// 安卓Chrome 32 及以上版本,若帶有 width=device-width 的 meta 標(biāo)簽也是無需 FastClick 的if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {return true;}}// 其它的就肯定是桌面級(jí)的 Chrome 了,更不需要 FastClick 啦} else {return true;}}if (deviceIsBlackBerry10) { //黑莓,和上面安卓同理,就不寫注釋了blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {metaViewport = document.querySelector('meta[name=viewport]');if (metaViewport) {if (metaViewport.content.indexOf('user-scalable=no') !== -1) {return true;}if (document.documentElement.scrollWidth <= window.outerWidth) {return true;}}}}// 帶有 -ms-touch-action: none / manipulation 特性的 IE10 會(huì)禁用雙擊放大,也沒有 300ms 時(shí)延if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {return true;}// Firefox檢測(cè),同上firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];if (firefoxVersion >= 27) {metaViewport = document.querySelector('meta[name=viewport]');if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {return true;}}// IE11 推薦使用沒有“-ms-”前綴的 touch-action 樣式特性名if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {return true;}return false;};

基本上都是一些能禁用 300ms 時(shí)延的瀏覽器嗅探,它們都沒必要使用 Fastclick,所以會(huì)返回 true 回構(gòu)造函數(shù)停止下一步執(zhí)行。

由于安卓手Q的 ua 會(huì)被匹配到?/Chrome\/([0-9]+)/,故帶有?'user-scalable=no' meta 標(biāo)簽的安卓手Q頁會(huì)被 FastClick?視為無需處理頁。

這也是為何在安卓手Q里沒有開頭提及問題的原因。

我們繼續(xù)看構(gòu)造函數(shù),它直接給 layer(即body)添加了click、touchstart、touchmove、touchend、touchcancel(若是安卓還有 mouseover、mousedown、mouseup)事件監(jiān)聽:

//安卓則做額外處理if (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);

注意在這段代碼上面還利用了 bind 方法做了處理,這些事件回調(diào)中的 this 都會(huì)變成 Fastclick 實(shí)例上下文。

另外還得留意,onclick 事件以及安卓的額外處理部分都是走的捕獲監(jiān)聽。

咱們分別看看這些事件回調(diào)分別都做了什么。

1. this.onTouchStart

FastClick.prototype.onTouchStart = function(event) {var targetElement, touch, selection;// 多指觸控的手勢(shì)則忽略if (event.targetTouches.length > 1) {return true;}targetElement = this.getTargetElementFromEventTarget(event.target); //一些較老的瀏覽器,target 可能會(huì)是一個(gè)文本節(jié)點(diǎn),得返回其DOM節(jié)點(diǎn)touch = event.targetTouches[0];if (deviceIsIOS) { //IOS處理// 若用戶已經(jīng)選中了一些內(nèi)容(比如選中了一段文本打算復(fù)制),則忽略selection = window.getSelection();if (selection.rangeCount && !selection.isCollapsed) {return true;}if (!deviceIsIOS4) { //是否IOS4//怪異特性處理——若click事件回調(diào)打開了一個(gè)alert/confirm,用戶下一次tap頁面的其它地方時(shí),新的touchstart和touchend//事件會(huì)擁有同一個(gè)touch.identifier(新的 touch event 會(huì)跟上一次觸發(fā)alert點(diǎn)擊的 touch event 一樣),//為避免將新的event當(dāng)作之前的event導(dǎo)致問題,這里需要禁用事件//另外chrome的開發(fā)工具啟用'Emulate touch events'后,iOS UA下的 identifier 會(huì)變成0,所以要做容錯(cuò)避免調(diào)試過程也被禁用事件了if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {event.preventDefault();return false;}this.lastTouchIdentifier = touch.identifier;// 如果target是一個(gè)滾動(dòng)容器里的一個(gè)子元素(使用了 -webkit-overflow-scrolling: touch) ,而且滿足:// 1) 用戶非常快速地滾動(dòng)外層滾動(dòng)容器// 2) 用戶通過tap停止住了這個(gè)快速滾動(dòng)// 這時(shí)候最后的'touchend'的event.target會(huì)變成用戶最終手指下的那個(gè)元素// 所以當(dāng)快速滾動(dòng)開始的時(shí)候,需要做檢查target是否滾動(dòng)容器的子元素,如果是,做個(gè)標(biāo)記// 在touchend時(shí)檢查這個(gè)標(biāo)記的值(滾動(dòng)容器的scrolltop)是否改變了,如果是則說明頁面在滾動(dòng)中,需要取消fastclick處理this.updateScrollParent(targetElement);}}this.trackingClick = true; //做個(gè)標(biāo)志表示開始追蹤click事件了this.trackingClickStart = event.timeStamp; //標(biāo)記下touch事件開始的時(shí)間戳this.targetElement = targetElement;//標(biāo)記touch起始點(diǎn)的頁面偏移值this.touchStartX = touch.pageX;this.touchStartY = touch.pageY;// this.lastClickTime 是在 touchend 里標(biāo)記的事件時(shí)間戳// this.tapDelay 為常量 200 (ms)// 此舉用來避免 phantom 的雙擊(200ms內(nèi)快速點(diǎn)了兩次)觸發(fā) click// 反正200ms內(nèi)的第二次點(diǎn)擊會(huì)禁止觸發(fā)其默認(rèn)事件if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {event.preventDefault();}return true;};

順道看下這里的?this.updateScrollParent:

/*** 檢查target是否一個(gè)滾動(dòng)容器里的子元素,如果是則給它加個(gè)標(biāo)記*/FastClick.prototype.updateScrollParent = function(targetElement) {var scrollParent, parentElement;scrollParent = targetElement.fastClickScrollParent; if (!scrollParent || !scrollParent.contains(targetElement)) {parentElement = targetElement;do {if (parentElement.scrollHeight > parentElement.offsetHeight) {scrollParent = parentElement;targetElement.fastClickScrollParent = parentElement;break;}parentElement = parentElement.parentElement;} while (parentElement);}// 給滾動(dòng)容器加個(gè)標(biāo)志fastClickLastScrollTop,值為其當(dāng)前垂直滾動(dòng)偏移if (scrollParent) {scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;}};

另外要注意的是,在 onTouchStart 里被標(biāo)記為 true 的?this.trackingClick 屬性,都會(huì)在其它事件回調(diào)(比如 ontouchmove )的開頭做檢測(cè),如果沒被賦值過,則直接忽略:

if (!this.trackingClick) {return true;}

當(dāng)然在 ontouchend 事件里會(huì)把它重置為 false。

2. this.onTouchMove

這段代碼量好少:

FastClick.prototype.onTouchMove = function(event) {//不是需要被追蹤click的事件則忽略if (!this.trackingClick) {return true;}// 如果target突然改變了,或者用戶其實(shí)是在移動(dòng)手勢(shì)而非想要click// 則應(yīng)該清掉this.trackingClick和this.targetElement,告訴后面的事件你們也不用處理了if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {this.trackingClick = false;this.targetElement = null;}return true;};

看下這里用到的?this.touchHasMoved 原型方法:

//判斷是否移動(dòng)了//this.touchBoundary是常量,值為10//如果touch已經(jīng)移動(dòng)了10個(gè)偏移量單位,則應(yīng)當(dāng)作為移動(dòng)事件處理而非click事件FastClick.prototype.touchHasMoved = function(event) {var touch = event.changedTouches[0], boundary = this.touchBoundary;if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {return true;}return false;};

3. onTouchEnd

FastClick.prototype.onTouchEnd = function(event) {var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;if (!this.trackingClick) {return true;}// 避免 phantom 的雙擊(200ms內(nèi)快速點(diǎn)了兩次)觸發(fā) click// 我們?cè)?ontouchstart 里已經(jīng)做過一次判斷了(僅僅禁用默認(rèn)事件),這里再做一次判斷if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {this.cancelNextClick = true; //該屬性會(huì)在 onMouse 事件中被判斷,為true則徹底禁用事件和冒泡return true;}//this.tapTimeout是常量,值為700//識(shí)別是否為長(zhǎng)按事件,如果是(大于700ms)則忽略if ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) {return true;}// 得重置為false,避免input事件被意外取消// 例子見 https://github.com/ftlabs/fastclick/issues/156this.cancelNextClick = false;this.lastClickTime = event.timeStamp; //標(biāo)記touchend時(shí)間,方便下一次的touchstart做雙擊校驗(yàn) trackingClickStart = this.trackingClickStart;//重置 this.trackingClick 和 this.trackingClickStartthis.trackingClick = false;this.trackingClickStart = 0;// iOS 6.0-7.*版本下有個(gè)問題 —— 如果layer處于transition或scroll過程,event所提供的target是不正確的// 所以咱們得重找 targetElement(這里通過 document.elementFromPoint 接口來尋找)if (deviceIsIOSWithBadTarget) { //iOS 6.0-7.*版本touch = event.changedTouches[0]; //手指離開前的觸點(diǎn)// 有些情況下 elementFromPoint 里的參數(shù)是預(yù)期外/不可用的, 所以還得避免 targetElement 為 nulltargetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;// target可能不正確需要重找,但fastClickScrollParent是不會(huì)變的targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;}targetTagName = targetElement.tagName.toLowerCase();if (targetTagName === 'label') { //是label則激活其指向的組件forElement = this.findControl(targetElement);if (forElement) {this.focus(targetElement);//安卓直接返回(無需合成click事件觸發(fā),因?yàn)辄c(diǎn)擊和激活元素不同,不存在點(diǎn)透)if (deviceIsAndroid) {return false;}targetElement = forElement;}} else if (this.needsFocus(targetElement)) { //非label則識(shí)別是否需要focus的元素//手勢(shì)停留在組件元素時(shí)長(zhǎng)超過100ms,則置空this.targetElement并返回//(而不是通過調(diào)用this.focus來觸發(fā)其聚焦事件,走的原生的click/focus事件觸發(fā)流程)//這也是為何文章開頭提到的問題中,稍微久按一點(diǎn)(超過100ms)textarea是可以把光標(biāo)定位在正確的地方的原因//另外iOS下有個(gè)意料之外的bug——如果被點(diǎn)擊的元素所在文檔是在iframe中的,手動(dòng)調(diào)用其focus的話,//會(huì)發(fā)現(xiàn)你往其中輸入的text是看不到的(即使value做了更新),so這里也直接返回if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {this.targetElement = null;return false;}this.focus(targetElement);this.sendClick(targetElement, event); //立即觸發(fā)其click事件,而無須等待300ms//iOS4下的 select 元素不能禁用默認(rèn)事件(要確保它能被穿透),否則不會(huì)打開select目錄//有時(shí)候 iOS6/7 下(VoiceOver開啟的情況下)也會(huì)如此if (!deviceIsIOS || targetTagName !== 'select') {this.targetElement = null;event.preventDefault();}return false;}if (deviceIsIOS && !deviceIsIOS4) {// 滾動(dòng)容器的垂直滾動(dòng)偏移改變了,說明是容器在做滾動(dòng)而非點(diǎn)擊,則忽略scrollParent = targetElement.fastClickScrollParent;if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {return true;}}// 查看元素是否無需處理的白名單內(nèi)(比如加了名為“needsclick”的class)// 不是白名單的則照舊預(yù)防穿透處理,立即觸發(fā)合成的click事件if (!this.needsClick(targetElement)) {event.preventDefault();this.sendClick(targetElement, event);}return false;};

這段比較長(zhǎng),我們主要看這段:

} else if (this.needsFocus(targetElement)) { //非label則識(shí)別是否需要focus的元素//手勢(shì)停留在組件元素時(shí)長(zhǎng)超過100ms,則置空this.targetElement并返回//(而不是通過調(diào)用this.focus來觸發(fā)其聚焦事件,走的原生的click/focus事件觸發(fā)流程)//這也是為何文章開頭提到的問題中,稍微久按一點(diǎn)(超過100ms)textarea是可以把光標(biāo)定位在正確的地方的原因//另外iOS下有個(gè)意料之外的bug——如果被點(diǎn)擊的元素所在文檔是在iframe中的,手動(dòng)調(diào)用其focus的話,//會(huì)發(fā)現(xiàn)你往其中輸入的text是看不到的(即使value做了更新),so這里也直接返回if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {this.targetElement = null;return false;}this.focus(targetElement);this.sendClick(targetElement, event); //立即觸發(fā)其click事件,而無須等待300ms//iOS4下的 select 元素不能禁用默認(rèn)事件(要確保它能被穿透),否則不會(huì)打開select目錄//有時(shí)候 iOS6/7 下(VoiceOver開啟的情況下)也會(huì)如此if (!deviceIsIOS || targetTagName !== 'select') {this.targetElement = null;event.preventDefault();}return false;}

其中 this.needsFocus 用于判斷給定元素是否需要通過合成click事件來模擬聚焦:

//判斷給定元素是否需要通過合成click事件來模擬聚焦FastClick.prototype.needsFocus = function(target) {switch (target.nodeName.toLowerCase()) {case 'textarea':return true;case 'select':return !deviceIsAndroid; //iOS下的select得走穿透點(diǎn)擊才行case 'input':switch (target.type) {case 'button':case 'checkbox':case 'file':case 'image':case 'radio':case 'submit':return false;}return !target.disabled && !target.readOnly;default://帶有名為“bneedsfocus”的class則返回truereturn (/\bneedsfocus\b/).test(target.className);}};

另外這段說明了為何稍微久按一點(diǎn)(超過100ms)textarea ,我們是可以把光標(biāo)定位在正確的地方(會(huì)繞過后面調(diào)用 this.focus 的方法):

//手勢(shì)停留在組件元素時(shí)長(zhǎng)超過100ms,則置空this.targetElement并返回//(而不是通過調(diào)用this.focus來觸發(fā)其聚焦事件,走的原生的click/focus事件觸發(fā)流程)//這也是為何文章開頭提到的問題中,稍微久按一點(diǎn)(超過100ms)textarea是可以把光標(biāo)定位在正確的地方的原因//另外iOS下有個(gè)意料之外的bug——如果被點(diǎn)擊的元素所在文檔是在iframe中的,手動(dòng)調(diào)用其focus的話,//會(huì)發(fā)現(xiàn)你往其中輸入的text是看不到的(即使value做了更新),so這里也直接返回if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {this.targetElement = null;return false;}

接著咱們看看這兩行很重要的代碼:

this.focus(targetElement);this.sendClick(targetElement, event); //立即觸發(fā)其click事件,而無須等待300ms

所涉及的兩個(gè)原型方法分別為:

⑴ this.focus

FastClick.prototype.focus = function(targetElement) {var length;// 組件建議通過setSelectionRange(selectionStart, selectionEnd)來設(shè)定光標(biāo)范圍(注意這樣還沒有聚焦// 要等到后面觸發(fā) sendClick 事件才會(huì)聚焦)// 另外 iOS7 下有些input元素(比如 date datetime month) 的 selectionStart 和 selectionEnd 特性是沒有整型值的,// 導(dǎo)致會(huì)拋出一個(gè)關(guān)于 setSelectionRange 的模糊錯(cuò)誤,它們需要改用 focus 事件觸發(fā)if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') {length = targetElement.value.length;targetElement.setSelectionRange(length, length);} else {//直接觸發(fā)其focus事件 targetElement.focus();}};

注意,我們點(diǎn)擊?textarea 時(shí)調(diào)用了該方法,它通過?targetElement.setSelectionRange(length, length)?決定了光標(biāo)的位置在內(nèi)容的尾部(但注意,這時(shí)候還沒聚焦!!!)。

⑵ this.sendClick

真正讓 textarea 聚焦的是這個(gè)方法,它合成了一個(gè) click 方法立刻在textarea元素上觸發(fā)導(dǎo)致聚焦:

//合成一個(gè)click事件并在指定元素上觸發(fā)FastClick.prototype.sendClick = function(targetElement, event) {var clickEvent, touch;// 在一些安卓機(jī)器中,得讓頁面所存在的 activeElement(聚焦的元素,比如input)失焦,否則合成的click事件將無效if (document.activeElement && document.activeElement !== targetElement) {document.activeElement.blur();}touch = event.changedTouches[0];// 合成(Synthesise) 一個(gè) click 事件// 通過一個(gè)額外屬性確保它能被追蹤(tracked)clickEvent = document.createEvent('MouseEvents');clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);clickEvent.forwardedTouchEvent = true; // fastclick的內(nèi)部變量,用來識(shí)別click事件是原生還是合成的targetElement.dispatchEvent(clickEvent); //立即觸發(fā)其click事件 };FastClick.prototype.determineEventType = function(targetElement) {//安卓設(shè)備下 Select 無法通過合成的 click 事件被展開,得改為 mousedownif (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {return 'mousedown';}return 'click';};

經(jīng)過這么一折騰,咱們輕點(diǎn) textarea 后,光標(biāo)就自然定位到其內(nèi)容尾部去了。但是這里有個(gè)問題——排在 touchend 后的 focus 事件為啥沒被觸發(fā)呢?

如果 focus 事件能被觸發(fā)的話,那肯定能重新定位光標(biāo)到正確的位置呀。

咱們看下面這段:

//iOS4下的 select 元素不能禁用默認(rèn)事件(要確保它能被穿透),否則不會(huì)打開select目錄//有時(shí)候 iOS6/7 下(VoiceOver開啟的情況下)也會(huì)如此if (!deviceIsIOS || targetTagName !== 'select' ) {this.targetElement = null;event.preventDefault();}

通過 preventDefault 的阻擋,textarea 自然再也無法擁抱其 focus 寶寶了~

于是乎,我們?cè)谶@里做個(gè)改動(dòng)就能修復(fù)這個(gè)問題:

var _isTextInput = function(){return targetTagName === 'textarea' || (targetTagName === 'input' && targetElement.type === 'text');};if ((!deviceIsIOS || targetTagName !== 'select') && !_isTextInput()) {this.targetElement = null;event.preventDefault();}

或者:

if (!deviceIsIOS4 || targetTagName !== 'select') {this.targetElement = null;//給textarea加上“needsclick”的classif((!/\bneedsclick\b/).test(targetElement.className)){event.preventDefault(); } }

這里要吐槽下的是,Fastclick 把?this.needsClick 放到了 ontouchEnd 末尾去執(zhí)行,才導(dǎo)致前面說的加上了“needsclick”類名也無效的問題。

雖然問題原因找到也解決了,但咱們還是繼續(xù)看剩下的部分吧。

4. onMouse 和 onClick

//用于決定是否允許穿透事件(觸發(fā)layer的click默認(rèn)事件)FastClick.prototype.onMouse = function(event) {// touch事件一直沒觸發(fā)if (!this.targetElement) {return true;}if (event.forwardedTouchEvent) { //觸發(fā)的click事件是合成的return true;}// 編程派生的事件所對(duì)應(yīng)元素事件可以被允許// 確保其沒執(zhí)行過 preventDefault 方法(event.cancelable 不為 true)即可if (!event.cancelable) {return true;}// 需要做預(yù)防穿透處理的元素,或者做了快速(200ms)雙擊的情況if (!this.needsClick(this.targetElement) || this.cancelNextClick) {//停止當(dāng)前默認(rèn)事件和冒泡if (event.stopImmediatePropagation) {event.stopImmediatePropagation();} else {// 不支持 stopImmediatePropagation 的設(shè)備(比如Android 2)做標(biāo)記,// 確保該事件回調(diào)不會(huì)執(zhí)行(見126行)event.propagationStopped = true;}// 取消事件和冒泡 event.stopPropagation();event.preventDefault();return false;}//允許穿透return true;};//click事件常規(guī)都是touch事件衍生來的,也排在touch后面觸發(fā)。//對(duì)于那些我們?cè)趖ouch事件過程沒有禁用掉默認(rèn)事件的event來說,我們還需要在click的捕獲階段進(jìn)一步//做判斷決定是否要禁掉點(diǎn)擊事件(防穿透)FastClick.prototype.onClick = function(event) {var permitted;// 如果還有 trackingClick 存在,可能是某些UI事件阻塞了touchEnd 的執(zhí)行if (this.trackingClick) {this.targetElement = null;this.trackingClick = false;return true;}// 依舊是對(duì) iOS 怪異行為的處理 —— 如果用戶點(diǎn)擊了iOS模擬器里某個(gè)表單中的一個(gè)submit元素// 或者點(diǎn)擊了彈出來的鍵盤里的“Go”按鈕,會(huì)觸發(fā)一個(gè)“偽”click事件(target是一個(gè)submit-type的input元素)if (event.target.type === 'submit' && event.detail === 0) {return true;}permitted = this.onMouse(event);if (!permitted) { //如果點(diǎn)擊是被允許的,將this.targetElement置空可以確保onMouse事件里不會(huì)阻止默認(rèn)事件this.targetElement = null;}//沒有多大意義return permitted;};//銷毀Fastclick所注冊(cè)的監(jiān)聽事件。是給外部實(shí)例去調(diào)用的FastClick.prototype.destroy = function() {var layer = this.layer;if (deviceIsAndroid) {layer.removeEventListener('mouseover', this.onMouse, true);layer.removeEventListener('mousedown', this.onMouse, true);layer.removeEventListener('mouseup', this.onMouse, true);}layer.removeEventListener('click', this.onClick, true);layer.removeEventListener('touchstart', this.onTouchStart, false);layer.removeEventListener('touchmove', this.onTouchMove, false);layer.removeEventListener('touchend', this.onTouchEnd, false);layer.removeEventListener('touchcancel', this.onTouchCancel, false);};

常規(guī)需要阻斷點(diǎn)擊事件的操作,我們?cè)?touch 監(jiān)聽事件回調(diào)中已經(jīng)做了處理,這里主要是針對(duì)那些 touch 過程(有些設(shè)備甚至可能并沒有touch事件觸發(fā))沒有禁用默認(rèn)事件的 event 做進(jìn)一步處理,從而決定是否觸發(fā)原生的 click 事件(如果禁止是在 onMouse 方法里做的處理)。

小結(jié)

1. 在 fastclick 源碼的 addEventListener?回調(diào)事件中有很多的 return false/true。它們其實(shí)主要用于繞過后面的腳本邏輯,并沒有其它意義(它是不會(huì)阻止默認(rèn)事件的)。

所以千萬別把 jQuery 事件、或者 DOM0 級(jí)事件回調(diào)中的 return false 概念,跟 addEventListener 的混在一起了。

2. fastclick 的源碼其實(shí)很簡(jiǎn)單,有很大部分不外乎對(duì)一些怪異行為做 hack,其核心理念不外乎是——捕獲 target 事件,判斷 target 是要解決點(diǎn)透問題的元素,就合成一個(gè) click 事件在 target 上觸發(fā),同時(shí)通過 preventDefault 禁用默認(rèn)事件。

3. fastclick 雖好,但也有一些坑,還是得按需求對(duì)其修改,那么了解其源碼還是很有必要的。

轉(zhuǎn)載于:https://www.cnblogs.com/vajoy/p/5522114.html

總結(jié)

以上是生活随笔為你收集整理的FastClick 填坑及源码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

亚洲成人黄色网址 | 91在线视频 | 日韩在线无 | 黄色软件视频网站 | 色成人亚洲 | 五月天伊人 | 西西4444www大胆视频 | 在线视频 日韩 | 九九热在线精品 | 98涩涩国产露脸精品国产网 | 亚洲女人天堂成人av在线 | 日日夜夜噜噜噜 | 日韩网站在线观看 | www日韩在线 | 国产亲近乱来精品 | 国产麻豆精品久久一二三 | 亚洲高清免费在线 | 日本在线观看一区 | 极品久久久久 | 在线看国产视频 | 免费福利在线观看 | 亚洲国产黄色片 | 成人精品影视 | 日韩精品视频一二三 | 日韩av不卡在线 | 91在线色| 亚洲乱码中文字幕综合 | www.国产在线| 久久9视频| 97超碰人人模人人人爽人人爱 | 99精品热 | 午夜精品999| 成人蜜桃视频 | 久久婷婷开心 | 亚洲欧美日韩中文在线 | 激情视频网页 | 97偷拍视频 | 国产精品一区二区果冻传媒 | 日本在线观看中文字幕 | 综合久久久久久 | 久久免费精品视频 | 亚洲精品 在线视频 | 91中文在线 | 91亚洲精品久久久蜜桃网站 | 日韩在线免费高清视频 | 91亚洲欧美激情 | 在线播放日韩av | 在线观看亚洲精品视频 | 久久久99精品免费观看乱色 | 99精品国自产在线 | 黄色毛片在线看 | 三级a视频 | 久久久久久久国产精品影院 | 精品国产一区二区三区av性色 | 久久视频免费看 | 毛片1000部免费看 | 99久久精品一区二区成人 | 国产一级精品视频 | 日韩免费视频 | 国产精品一区二区免费看 | 精品 一区 在线 | 久久天天综合网 | 免费看黄色毛片 | 精品在线观看视频 | 成人网中文字幕 | 国产999精品视频 | 草久久影院 | 美女视频国产 | 国产网红在线观看 | 久久国产精品久久久久 | 国产999精品久久久久久麻豆 | 国产麻豆剧传媒免费观看 | 色网站在线免费 | 91精品麻豆 | 中文av在线播放 | 日韩丝袜在线观看 | 中文字幕999 | 欧美成人黄色片 | 日韩免费三区 | 在线中文字幕视频 | 国产视频一区在线免费观看 | 91精品一区二区三区蜜臀 | 97电影手机 | 久久久久亚洲精品中文字幕 | 精品网站999www| 欧美日本三级 | 日日爽视频 | 伊人色播 | 中文字幕视频一区二区 | 久久久免费精品国产一区二区 | 国产黄色精品视频 | 噜噜色官网 | 操高跟美女 | 婷婷亚洲综合五月天小说 | 揉bbb玩bbb少妇bbb | 免费观看丰满少妇做爰 | 久久一本综合 | 中文字幕在线看视频国产 | 成人av片免费看 | 日韩在线不卡av | 国产精品色 | 国产黄色精品在线 | 草久在线视频 | 久久久久久久久艹 | 国产精品久久久久久五月尺 | 亚洲成年人免费网站 | 天天干国产 | 91视频免费观看 | 色久五月 | 在线播放日韩av | 欧美性色黄| 久久国产精品影片 | 久久性生活片 | 日日久视频| 国产成人av电影在线 | 欧美性黄网官网 | 天天天干天天天操 | 国产精品久久久久久久久久久久冷 | 五月天狠狠操 | 夜夜干天天操 | 久久精品国产久精国产 | 成人毛片一区 | 欧美国产高清 | 亚洲精品a区 | 久久婷婷一区二区三区 | 深爱激情婷婷网 | 日韩中文在线视频 | 在线中文字幕一区二区 | 国产97在线观看 | 久久久久久久久久久精 | 国产一卡二卡在线 | 亚洲精选国产 | 国产色小视频 | 中文字幕一区二区三区视频 | 欧美日韩伦理在线 | 免费视频一级片 | 91免费国产在线观看 | 成人免费观看完整版电影 | 黄色在线观看污 | 久草视频在线免费 | 亚洲视频99 | 天天爽网站 | 91成人在线免费观看 | 国产视频1区2区3区 久久夜视频 | 在线免费看黄网站 | 91漂亮少妇露脸在线播放 | 亚洲综合激情小说 | 蜜臀av性久久久久蜜臀av | 1024手机基地在线观看 | 五月网婷婷 | 最新久久免费视频 | 成年人视频在线观看免费 | 免费www视频 | 91丨九色丨首页 | 久久最新 | 国产在线污 | 九草视频在线观看 | 精品久久久久久久久久久久久久久久 | 中文字幕免费一区 | 国产 日韩 欧美 在线 | 国产一级片免费观看 | 午夜在线免费视频 | 91精品在线播放 | 久久婷婷开心 | 超碰成人网 | 狠色在线 | 啪嗒啪嗒免费观看完整版 | 久久综合在线 | 美女网站在线免费观看 | 亚洲性xxxx | 激情欧美一区二区免费视频 | 视频一区在线免费观看 | 色五月情| 亚洲在线视频观看 | 欧美日韩国产综合一区二区 | 日韩中文久久 | 日韩视频图片 | 91麻豆福利| 国产精品一区二区免费在线观看 | a级国产乱理伦片在线观看 亚洲3级 | 99视频播放| 久久精品视频免费播放 | 在线观看一区 | 久久免费视频这里只有精品 | 久久精品精品电影网 | 国产精品久久久久久久久搜平片 | 国产精品久久久久久久久久尿 | 久久免费看a级毛毛片 | 亚洲欧美日韩精品一区二区 | 91视频首页| 免费av网址在线观看 | 久久天天躁 | 久久无码av一区二区三区电影网 | 亚洲香蕉在线观看 | 在线91色 | 在线免费观看黄色 | 国产成人av电影在线 | 成人av免费 | 婷婷视频在线播放 | 碰天天操天天 | 在线观看av中文字幕 | 五月婷婷操 | 五月婷婷欧美视频 | 久久综合婷婷国产二区高清 | 91香蕉视频色版 | 精品久久久久久一区二区里番 | 丁香婷婷在线观看 | 欧美一级电影在线观看 | av线上免费看 | www.国产精品| 国产精品区二区三区日本 | 亚洲精品午夜国产va久久成人 | av电影一区二区 | 亚洲成人网在线 | av福利在线看 | 91你懂的 | a在线播放 | 亚洲国产精品影院 | 波多野结衣最新 | 五月天婷婷在线观看视频 | 欧洲亚洲女同hd | 亚洲欧美一区二区三区孕妇写真 | 色综合激情久久 | 久草电影网| 狠狠激情中文字幕 | 免费三级影片 | 亚洲国产精品久久久久久 | 久久五月婷婷丁香 | 亚洲一区二区三区毛片 | 中文资源在线官网 | 91精品视频一区二区三区 | 激情久久综合网 | 毛片在线网 | 91大神dom调教在线观看 | 中文字幕乱码在线播放 | 国产一级在线观看 | 久艹视频在线观看 | 日韩精品视频免费专区在线播放 | 99精品区 | 麻豆传媒在线免费看 | 爱色婷婷| 日韩欧美综合在线视频 | 91在线永久 | 久久精品国亚洲 | 亚洲天堂网视频在线观看 | 99在线看| 国产亚洲欧洲 | 欧洲黄色片 | 国产 在线观看 | 激情欧美一区二区三区免费看 | 又紧又大又爽精品一区二区 | 五月天亚洲精品 | av再线观看 | 亚洲91中文字幕无线码三区 | 亚洲欧美在线综合 | 亚洲激情六月 | 亚洲成人黄色网址 | 天天干天天碰 | 国产3p视频 | 亚洲性视频 | 成人h视频| 日韩在线观看小视频 | 久久超碰网 | 国产精品久久久久久久久久东京 | 在线看v片 | 国产精品手机在线 | 国产精品99精品久久免费 | 日韩午夜av | 久久免费视频播放 | 久久久精品一区二区 | 久色 网 | www色,com| 亚洲黄污| 操高跟美女 | 亚洲精品在线视频播放 | 999国产 | 天天碰天天操视频 | 在线黄色毛片 | 人人干,人人爽 | 亚洲激情p | 在线观看91 | 久久婷婷开心 | 99精品视频免费全部在线 | 亚洲精品999 | 国产精品免费不卡 | 69av在线播放 | 欧美a视频| 五月天丁香视频 | 欧美视频二区 | 激情五月激情综合网 | 国产很黄很色的视频 | 亚洲免费一级电影 | 婷婷色综 | 精品久久久久一区二区国产 | 国产亚洲无 | 久久av免费 | 欧美另类69 | 2020天天干天天操 | 最近日本字幕mv免费观看在线 | 国产第一页在线观看 | 国产91成人在在线播放 | 成年人黄色在线观看 | 超碰在线日本 | 欧美另类网站 | 免费看污黄网站 | 日韩欧美高清免费 | 国产日女人 | 免费看污网站 | 超碰在线资源 | 91福利视频在线 | 在线只有精品 | 精品国产免费久久 | 久草色在线观看 | 国产精品免费一区二区三区在线观看 | 色婷婷av在线 | 国产精品午夜久久 | 麻豆精品视频在线观看免费 | 亚洲精品资源 | 岛国av在线 | 亚洲最大成人网4388xx | 一区二区三区国产精品 | 国产亚洲欧美日韩高清 | 日日弄天天弄美女bbbb | 日韩在线高清免费视频 | 亚洲成色 | 亚洲精品在线播放视频 | 91久久一区二区 | 免费观看性生交大片3 | 五月丁香| 在线观看成人网 | 国产精品精品视频 | 黄色网免费 | 久久一区精品 | 国产中文在线播放 | 成人禁用看黄a在线 | 亚洲精选久久 | 国产96在线 | 国产片免费在线观看视频 | 婷婷六月中文字幕 | 麻豆视频国产 | 久久久国产精品亚洲一区 | 麻豆影视在线免费观看 | 日本黄色免费电影网站 | 成年人免费在线观看 | 国产中文字幕第一页 | 欧美精品久久天天躁 | 一区二区三区影院 | 国产精品剧情 | 欧美精品久久99 | 国产一级做a| 欧美成人999| 韩国av三级 | 人人爽人人爽 | 亚洲不卡av一区二区三区 | 蜜臀精品久久久久久蜜臀 | 中文字幕一区二区三 | 69视频在线播放 | 一本到在线 | 伊人影院99 | 在线观看蜜桃视频 | 免费在线一区二区三区 | 国产中文字幕一区二区三区 | 久草精品视频在线播放 | 尤物九九久久国产精品的分类 | 亚洲视频axxx | 国产精品伦一区二区三区视频 | 久久一区二区三区四区 | 天天色天天操天天爽 | 91成人免费在线视频 | 国产一区二区不卡视频 | 成人国产精品久久久久久亚洲 | 人人玩人人添人人 | 久久你懂的 | 福利视频入口 | 99色精品视频| 色综久久 | 久久爱资源网 | 免费在线成人av | 国产99久久久国产精品免费二区 | 欧美精品九九99久久 | 亚洲精品视频在线观看网站 | 五月婷婷中文字幕 | 亚洲高清在线精品 | 日韩亚洲国产精品 | 超碰在线94| 日本黄色免费播放 | 国产一级免费电影 | 女女av在线 | 免费福利片2019潦草影视午夜 | 99久久精品久久久久久清纯 | 日韩精品在线看 | 日韩一区二区三区免费视频 | 国产探花视频在线播放 | 免费成人av网站 | 五月婷综合 | 午夜狠狠操 | 久草干 | 国产视频1区2区 | 精品国产资源 | 九九久久久久久久久激情 | 精品一区二区在线观看 | 国产一级久久久 | 日精品在线观看 | 日韩动漫免费观看高清完整版在线观看 | 色吊丝av中文字幕 | 久久成视频 | 国产成人在线观看免费 | 人人爽人人爽 | 99九九视频 | 婷婷久久一区二区三区 | 久久久久久久久久久网 | 在线精品视频免费播放 | 青春草视频在线播放 | 精品视频久久久久久 | 高清在线一区二区 | 久久免费国产精品 | 天天干天天射天天爽 | 日韩在线观看小视频 | 亚洲午夜精品久久久久久久久 | 色综合天天干 | 国内揄拍国产精品 | 日韩欧美国产成人 | 日韩一区精品 | 中文字幕永久 | 久久这里只有精品23 | 在线国产欧美 | 中文字幕在线久一本久 | 国产高清一 | 午夜久久久久久久 | 久久99精品国产91久久来源 | 亚洲精品美女在线观看播放 | 99中文字幕 | 日韩精品中文字幕在线播放 | 亚洲 欧美 国产 va在线影院 | 精品视频在线免费观看 | 99视频在线观看免费 | 揉bbb玩bbb少妇bbb | 黄色免费大片 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 国产成人av在线 | 激情视频一区二区 | 中文字幕中文字幕在线中文字幕三区 | 中文字幕影视 | 成人亚洲综合 | 欧美日韩亚洲在线观看 | 亚洲成av人片在线观看 | 丁香午夜| 国产免费视频在线 | 天天操伊人 | 国产精品粉嫩 | 欧美国产日韩在线视频 | 久久这里有 | 香蕉网在线播放 | 男女免费视频观看 | 97超碰总站 | 999日韩| 99九九视频 | 狠狠综合 | 福利视频一区二区 | 激情在线网 | 嫩小bbbb摸bbb摸bbb | 国产精品久久久久999 | 波多野结衣视频在线 | 在线电影av | 91麻豆精品国产91久久久久久 | 九月婷婷综合网 | 天天爱天天射天天干天天 | 国产成人在线播放 | 国产无吗一区二区三区在线欢 | 波多野结衣资源 | 最近中文字幕大全中文字幕免费 | 国产乱视频 | 久久免费视频在线 | 奇米影视四色8888 | www.xxxx欧美 | 国产成人综合在线观看 | 婷婷伊人综合 | 天天射夜夜爽 | 在线观看理论 | 久久国产影院 | 免费不卡中文字幕视频 | 日韩免费b | 高清av网 | 五月婷在线 | www.97视频| 亚洲欧美经典 | 91精品视频在线观看免费 | 波多野结衣在线观看一区二区三区 | 91av九色| 欧美成人按摩 | 日韩欧美一区二区在线 | 国产片免费在线观看视频 | 四虎国产永久在线精品 | 亚洲区视频在线观看 | 国产做aⅴ在线视频播放 | 国产丝袜| 久久高清免费观看 | 91中文字幕在线视频 | 日本公妇在线观看 | 日本三级吹潮在线 | 婷婷爱五月天 | 国产在线观看高清视频 | 中日韩欧美精彩视频 | 日韩va在线观看 | 日韩久久精品一区二区三区下载 | 久久精品日韩 | 午夜久久美女 | 久久影院一区 | 欧美日韩国产一区二区三区 | 亚洲精品97 | 久久久国产精品一区二区中文 | 91福利区一区二区三区 | 国产精品一区二区三区久久久 | 久久官网 | 色婷婷天天干 | 9幺看片| 99久热在线精品视频成人一区 | 久久黄网站 | 国产夫妻性生活自拍 | 天天射一射| 国产免费中文字幕 | 亚洲精品97 | 中文字幕一区三区 | 欧美极品xxx | 伊人精品影院 | 中国精品一区二区 | 777久久久 | 日韩精品1区2区 | 嫩模bbw搡bbbb搡bbbb | 干干日日| 99国产视频在线 | 麻豆综合网| 精品国产欧美一区二区 | 99久久久久 | 丁香六月天 | 亚洲精品综合欧美二区变态 | 日韩国产在线观看 | 久久精品久久99精品久久 | 久久99久久99精品免费看小说 | 日本久久久久久 | 欧美极品xxx | 免费在线观看午夜视频 | 国产91精品一区二区 | 人人插人人射 | 黄色av电影在线观看 | 欧美韩国日本在线 | 日韩免费在线 | 91女子私密保健养生少妇 | 日韩sese | 美女精品久久 | 亚洲黄色在线观看 | 国产传媒中文字幕 | 亚洲高清在线精品 | 国产精品久久久久久久久久久久久久 | 久久开心激情 | 中文字幕成人在线观看 | 亚洲欧美成人综合 | 国产午夜精品一区二区三区四区 | 看片的网址 | 中文字幕免费观看 | 色婷婷狠狠五月综合天色拍 | 婷婷六月在线 | 99久久精品无免国产免费 | 波多野结衣在线中文字幕 | 久久视频免费看 | www.午夜视频 | 91色一区二区三区 | 欧美日韩免费在线观看视频 | 国精产品满18岁在线 | 久草在线视频精品 | 麻花天美星空视频 | www久久国产| 亚洲成av人片在线观看 | 久久久久久久久久免费 | 精品免费国产一区二区三区四区 | 99在线观看视频网站 | 视频在线观看国产 | 在线电影91 | 国产三级香港三韩国三级 | 最近中文字幕免费观看 | 韩国一区二区在线观看 | 一区二区三区电影在线播 | 黄色a三级 | 亚洲欧洲视频 | 免费a级黄色毛片 | 久久99亚洲网美利坚合众国 | 九色视频网| 毛片网站免费在线观看 | 欧美色就是色 | 久久国产网 | 国产精品成人av在线 | 欧美午夜寂寞影院 | 国内精品在线一区 | 色狠狠狠| 91精品国产成| 九色福利视频 | 成片人卡1卡2卡3手机免费看 | 日韩1级片 | 色婷婷亚洲婷婷 | 999久久久国产精品 高清av免费观看 | 狂野欧美激情性xxxx欧美 | 天天爱天天操天天爽 | 青青视频一区 | 亚洲综合五月天 | 婷婷在线资源 | 在线午夜电影神马影院 | 日韩精品免费在线 | 国产污视频在线观看 | 亚洲黄色免费在线 | 精品不卡av | 伊人婷婷激情 | 99久久久久久国产精品 | 日韩精品国产一区 | 午夜av免费在线观看 | 精品综合久久久 | 九九视频网| 国产专区在线看 | 97视频在线观看成人 | 国产成人精品日本亚洲999 | 视频在线一区二区三区 | 欧美一级黄大片 | 首页中文字幕 | 欧美一二三视频 | 99热精品久久 | 福利久久久 | 97操操操 | 91在线视频在线观看 | 92国产精品久久久久首页 | 综合亚洲视频 | 精品一区二区综合 | 色播99| 视频在线在亚洲 | 国产精品久一 | 五月婷婷在线播放 | 欧美99精品| 国产精品免费一区二区 | 中文字幕高清 | 天天综合网~永久入口 | 国产欧美高清 | 日韩视频免费在线观看 | 国产美女视频免费观看的网站 | 91精品久久久久久 | 五月婷婷中文字幕 | 91香蕉国产在线观看软件 | 一区二区三区日韩在线观看 | 国产精品久久久亚洲 | 亚洲欧美日韩国产一区二区 | 国产黄色大片 | 国产成视频在线观看 | 国产高清福利在线 | 婷婷在线五月 | 天天爽夜夜爽人人爽一区二区 | 91日韩免费 | av免费看看| 最近中文字幕完整视频高清1 | 亚洲精品视频第一页 | 在线观看色网 | 人人超碰97| 三级av在线播放 | 国产一区观看 | 久久黄色小说 | 激情综合电影网 | 懂色av一区二区三区蜜臀 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 日韩欧美高清不卡 | 婷婷综合 | 成人a级免费视频 | 久久99精品久久只有精品 | 在线观看视频你懂得 | 久久免费看av | 天天av在线播放 | 在线观看日韩一区 | 欧美精品在线一区二区 | 日韩av影视在线观看 | 亚洲成人av一区二区 | 五月导航 | 色婷婷啪啪免费在线电影观看 | 免费在线观看av网站 | 国产在线综合视频 | 国产亚洲精品无 | 亚洲午夜久久久久久久久电影网 | 成人av免费网站 | 在线 视频 一区二区 | 91久久奴性调教 | 久久不卡免费视频 | 在线观看视频国产一区 | 正在播放亚洲精品 | 日韩和的一区二在线 | 91最新视频在线观看 | 日韩极品在线 | 久草免费在线视频观看 | 久久免费观看少妇a级毛片 久久久久成人免费 | 在线观看黄色小视频 | 天天做天天爱天天爽综合网 | 国产白浆视频 | 日韩系列在线观看 | 欧美二区在线播放 | 国产黄色片一级三级 | 亚洲精品美女在线 | 在线观看中文 | 91视频国产高清 | 狠狠狠干 | 久操视频在线观看 | 在线视频免费观看 | 久久久久久久久久久久99 | 久久夜色精品国产欧美乱 | 人人玩人人添人人澡超碰 | 97超碰国产精品 | 九九热国产视频 | av看片在线 | 激情视频一区二区三区 | 在线观看国产一区 | 91丨九色丨丝袜 | 亚洲免费黄色 | 亚洲丝袜一区二区 | 久久玖 | 又黄又网站 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 国产无区一区二区三麻豆 | 国产精品一区二区白浆 | 国产精品不卡视频 | 91视频在线自拍 | 久久久久免费网站 | 综合久久久久 | 97精产国品一二三产区在线 | 国产精品综合在线观看 | 就色干综合 | 国产一区二区日本 | 欧美日在线 | 久久久国产毛片 | 国产99久久久国产精品 | 久久人人爽av | 免费中文字幕在线观看 | 手机av观看 | 天天·日日日干 | 91精品视频免费观看 | 国产手机视频精品 | 天天插综合网 | 99热.com| 欧美日韩激情视频8区 | 99视频在线精品国自产拍免费观看 | 久久午夜色播影院免费高清 | 国产淫片| 狠狠操电影网 | 日本乱视频| 91免费高清视频 | 国产精品福利小视频 | 偷拍精品一区二区三区 | 亚洲国产精品推荐 | 少妇bbw搡bbbb搡bbb | 亚洲黑丝少妇 | 精品国产乱码久久久久久浪潮 | 日本视频精品 | 欧美影片 | 国产一区二区免费在线观看 | 亚洲欧洲国产日韩精品 | 97精品国产97久久久久久 | 2023亚洲精品国偷拍自产在线 | 免费在线观看国产精品 | 欧美天天干 | 国产香蕉av | 日韩国产精品一区 | 欧美在线aaa | 欧美日韩在线免费视频 | 国产白浆视频 | 成人小视频在线观看免费 | 国产精品99久久久久 | 激情综合国产 | 成人天堂网 | 成人av电影免费观看 | 永久免费毛片 | 日韩欧美在线免费观看 | 久久99精品久久久久久三级 | 国产在线一线 | 亚洲欧洲精品一区二区精品久久久 | 中文字幕乱码在线播放 | 日韩精品免费一区二区三区 | 亚洲男男gaygayxxxgv| 免费观看视频的网站 | 69国产成人综合久久精品欧美 | av福利在线播放 | 韩国av在线 | 国产精品手机视频 | 91视频在线国产 | 国产精品嫩草69影院 | 亚洲精品久久视频 | 91tv国产成人福利 | a天堂一码二码专区 | 欧美在线a视频 | 国产精品免费观看国产网曝瓜 | 91av原创| 日韩一级黄色大片 | 色激情五月 | 久久99中文字幕 | 91.麻豆视频| 中文字幕成人 | 亚洲国产久 | 日韩1页| 草久草久| 日韩欧美一区二区三区在线观看 | 免费网站污 | 亚洲精品乱码久久久久久 | 日韩欧美在线观看一区 | 色婷婷激婷婷情综天天 | 懂色av懂色av粉嫩av分享吧 | 久久最新视频 | 人人爽人人爽人人片av免 | 国产黄色在线观看 | 婷婷干五月 | 91香蕉嫩草 | 日韩精品久久久久久久电影99爱 | 久久久久久高潮国产精品视 | 中文字幕视频网 | 久久字幕网 | 久久久久色 | 在线观看日本韩国电影 | 日本精品视频一区 | av成人免费网站 | 精品亚洲视频在线观看 | 最近中文字幕mv免费高清在线 | 久久久久久久免费看 | 成年美女黄网站色大片免费看 | 国产不卡一区二区视频 | 五月天激情视频 | 免费观看一区二区 | 国产精品毛片完整版 | 99久热 | 亚洲男女精品 | av高清在线 | 91免费版成人 | 夜夜高潮夜夜爽国产伦精品 | 中文字幕有码在线 | 日韩av图片 | 日韩免费高清在线观看 | 色香com.| 欧美在线视频第一页 | 99精品视频精品精品视频 | 久久深爱网 | 亚洲精品黄色片 | 成人久久18免费网站麻豆 | 成人免费xxxxxx视频 | 亚洲午夜精品一区二区三区电影院 | 日韩网站在线免费观看 | 在线观看 亚洲 | 正在播放国产一区二区 | 成片视频免费观看 | 少妇bbw揉bbb欧美 | 又黄又爽又湿又无遮挡的在线视频 | 午夜精品视频在线 | 深爱开心激情网 | 国产大片免费久久 | 国产理论在线 | 亚洲精品国产品国语在线 | 天天干夜夜夜操天 | 中文字幕在线观看视频免费 | 亚洲精品在线免费 | 中文字幕第一页av | www.天天草 | 久久久久亚洲精品 | 草久久av| 精品一二三四五区 | 日韩av电影中文字幕 | 国产亚洲成av片在线观看 | 狠狠操欧美| 天天av资源 | 国产精品99久久久久 | 狠狠色丁香久久婷婷综合丁香 | 久久在线观看视频 | 免费久久精品视频 | 欧美性护士 | 成人一级影视 | 欧美性另类 | 色国产在线 | 韩国av不卡 | 欧美精品久久久久 | 在线观看黄色的网站 | 日韩免费电影一区二区 | 91麻豆精品国产自产 | 黄色天堂在线观看 | 伊人电影在线观看 | 91精品一区二区三区蜜臀 | aaa日本高清在线播放免费观看 | 欧美极品xxxxx | 欧美亚洲免费在线一区 | 欧美疯狂性受xxxxx另类 | 久久国产精品色婷婷 | 久久一区国产 | 亚洲精品男人天堂 | 成人va天堂 | 久久精品视频播放 | av色影院 | 99精品视频在线观看 | 国产麻豆视频网站 | 国产精品第一页在线观看 | 久久综合精品国产一区二区三区 | 国产小视频国产精品 | 狠狠狠狠狠狠天天爱 | 久久视频在线观看免费 | 亚洲一级久久 | 久久久首页 | 国产成人一区在线 | www.国产在线观看 | 欧美日bb | 少妇性bbb搡bbb爽爽爽欧美 | 亚洲一区二区三区在线看 | 亚洲天堂网视频在线观看 | 狠狠干电影 | 欧美极品少妇xbxb性爽爽视频 | 99操视频| 亚洲精品中文字幕在线观看 | 欧美综合干| 国产亚洲欧美精品久久久久久 | 天天综合导航 | 国产精品久久久久久麻豆一区 | 久久观看| 在线中文字幕播放 | 久av电影| 特级a老妇做爰全过程 | 国产精品久久久久久久午夜片 | 久久综合久久综合这里只有精品 | 草久久久久久久 | 97精品国产一二三产区 | 天堂av在线免费观看 | 91av蜜桃| 亚洲午夜精品久久久久久久久 | 91欧美国产 | 亚洲人成人99网站 | 婷婷亚洲五月 | 国产麻豆剧果冻传媒视频播放量 | 夜夜天天干| 精品免费视频 | 国产欧美中文字幕 | 这里只有精品视频在线 | 天天综合久久 | 粉嫩aⅴ一区二区三区 | 久久久久久国产精品免费 | 国产视频美女 | 欧美成人一二区 | 中文字幕一区二区三区四区在线视频 | 四虎成人精品永久免费av | 亚洲黄a| 亚洲成人在线免费 | 久久视频一区二区 | 午夜精品久久久久久久99 | 国产精品视频地址 | 亚洲精品在线视频网站 | 国产精品麻| 深夜国产在线 | 久久国产精品一国产精品 | 色全色在线资源网 | 国产精品白虎 | 中文字幕在线观看日本 | 99精品在线免费视频 | 91成人在线视频观看 | 午夜国产福利在线观看 | 婷婷丁香国产 | 久青草影院| www.色午夜,com | 国产在线a | 波多野结衣日韩 | 特黄免费av| 欧美在线视频a | 91av官网 | 国产91九色蝌蚪 | 狠狠夜夜 | 久久久久久久久久久久电影 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 亚洲激情在线观看 | 综合婷婷丁香 | 999成人精品 | 久久成人麻豆午夜电影 | 久久一区二区三区超碰国产精品 | 久久久久久美女 | 最近免费中文字幕mv在线视频3 | 最近中文字幕视频完整版 | 美女在线黄| 精品1区二区 | 色综合久久久久综合 | 玖操| 久久久久麻豆v国产 | 欧美色婷 | 国产96在线 | 亚洲欧美日韩精品一区二区 | 中文字幕日本在线观看 | 九九99视频 | 亚洲综合视频在线 | 中文字幕在线不卡国产视频 | www.夜夜草 | 99视频+国产日韩欧美 | 蜜桃av久久久亚洲精品 | 丁香六月婷婷开心 | 精品欧美一区二区精品久久 | 999一区二区三区 | av看片在线观看 | 欧美日韩视频一区二区三区 | 亚洲综合激情 | 99热在线看 | 97成人精品视频在线播放 |