我在帶有大鏈接的頁面上使用FastClick,因爲我想繞過移動瀏覽器中水龍頭的300毫秒延遲。對於鏈接':active
狀態,我有一個「高亮」風格,並且由於FastClick的原因,它正在快速正常啓動。有沒有辦法可以防止fastclick在滾動中觸發「活動」狀態?
我的問題是 - 在移動Safari至少 - 它也會觸發,而你點擊和滑動滾動頁面。這讓你覺得你不能在沒有它的情況下滾動頁面,因爲它認爲你想要點擊鏈接。
有人可以在有人滾動時阻止它開火嗎?
我在帶有大鏈接的頁面上使用FastClick,因爲我想繞過移動瀏覽器中水龍頭的300毫秒延遲。對於鏈接':active
狀態,我有一個「高亮」風格,並且由於FastClick的原因,它正在快速正常啓動。有沒有辦法可以防止fastclick在滾動中觸發「活動」狀態?
我的問題是 - 在移動Safari至少 - 它也會觸發,而你點擊和滑動滾動頁面。這讓你覺得你不能在沒有它的情況下滾動頁面,因爲它認爲你想要點擊鏈接。
有人可以在有人滾動時阻止它開火嗎?
也許你可以將needsclick
類添加到身體?
<body class="needsclick">
...
</body>
只是一個想法:)
有趣的問題! +1
此問題與FastClick無關,但FastClick確實爲您的問題提供了更復雜的解決方案。所以我會堅持使用純JavaScript和Raw Touch Events)
在移動觸摸設備上,由於平臺特有的原因,webview的實現與桌面Web瀏覽器顯着不同。 在這種情況下,一個重要的功能是在web視圖中動態滾動。 Momentum Scrolling是設備的硬件加速功能。因此,當屏幕上有可滾動區域時,硬件會識別觸摸並將200毫秒倒數計時器附加到可滾動區域,當觸發時,該區域將進入硬件加速滾動。當硬件處於該狀態時,它不會廣播觸摸事件,因爲它們特定於硬件加速滾動。可以取消定時器,並通過在提供的200毫秒內對觸摸事件使用preventDefault來防止動量滾動。
下面是我如何解決這個問題。我假設你使用本地滾動,即overflow:scroll
。 該方法將一個touchstart
事件附加到您想要觸摸的元素。 一旦touchstart
事件觸發,事件處理程序將touchend
,touchmove
和touchcancel
事件附加到目標元素。啓動setTimout計時器,可在140ms後刪除新添加的事件。
這裏是我的生產代碼中的一些片斷: 我從集合添加和刪除事件的兩個事件方法:
var eventify = (function() {
function eventify(type, el, callback, phase) {
phase = phase || false;
if ((el.constructor.toString().contains('NodeList')) || (el.constructor.toString().contains('HTMLCollection'))) {
[].forEach.call(el, function (element) {
if (!element.hasEvent(type)) {
element.addEvent(type);
HTMLElement.prototype.addEventListener.apply(element, [type, callback, phase]);
}
});
} else {
if (!el.hasEvent(type)) {
el.addEvent(type);
HTMLElement.prototype.addEventListener.apply(el, [type, callback, phase]);
}
}
return callback;
}
return eventify
})();
var uneventify = (function() {
function uneventify(type, el, callback) {
if ((el.constructor.toString().contains('NodeList')) || (el.constructor.toString().contains('HTMLCollection'))) {
[].forEach.call(el, function (element) {
if (element.hasEvent(type)) {
element.removeEvent(type);
HTMLElement.prototype.removeEventListener.apply(element, [type, callback]);
}
});
} else {
if (el.hasEvent(type)) {
el.removeEvent(type);
HTMLElement.prototype.removeEventListener.apply(el, [type, callback]);
}
}
}
return uneventify
})();
然後我有在滾動自來水事件tapify方法:
var tapify = (function() {
function tapify(el, callback) {
eventify('touchstart', el, function (e) {
var that = this;
var start = e.pageY;
var target = e.target;
function dynamicEvents() {
var endfn = eventify('touchend', target, function (evt) {
e.preventDefault();
e.stopImmediatePropagation();
evt.preventDefault();
evt.stopImmediatePropagation();
uneventify('touchmove', target, movefn);
uneventify('touchend', target, endfn);
uneventify('touchcancel', target, cancelfn);
callback && callback(target);
});
var cancelfn = eventify('touchcancel', target, function (evt) {
e.preventDefault();
e.stopImmediatePropagation();
evt.preventDefault();
evt.stopImmediatePropagation();
uneventify('touchmove', target, movefn);
uneventify('touchend', target, endfn);
uneventify('touchcancel', target, cancelfn);
callback && callback(target);
});
var movefn = eventify('touchmove', target, function (evt) {
var distance = start - evt.pageY;
if (distance > 20) {
uneventify('touchend', target, endfn);
uneventify('touchcancel', target, cancelfn);
uneventify('touchmove', el, movefn);
}
});
setTimeout(function() {
uneventify('touchmove', target, movefn);
uneventify('touchend', target, endfn);
uneventify('touchcancel', target, cancelfn);
}, 140);
}
if (global.isIos) setTimeout(function() {
dynamicEvents();
}, 60);
else dynamicEvents();
}, false);
}
return tapify;
})();
我使用global.isIos來標識目標設備。 Android停止將觸發事件發送到webview ater 200ms。
然後向事件附加到一個元素或元素的集合,使用方法:
tapify(document.querySelectorAll('button'), function (e) {
//your event handler here!!
});
希望這有助於
可以使用相同的方法在原生滾動表面上進行滑動和拖動事件。 –
感謝您的回覆! 現在我希望能夠嘗試與FastClick兼容的東西......並且作爲一名JS新手,我承認自己的答案已經超出了我的觀點,但是我沒有看到它與FastClick的聯繫。 但是,如果我變得勇敢,我會嘗試將一些代碼添加到我的項目中。 –
我建議你只在需要它的元素上附加FastClick,而不是在document.body –
謝謝...這實際上會阻止FastClick從控件工作的。 –