簡體   English   中英

有沒有辦法防止fastclick在滾動時觸發“活動”狀態?

[英]Is there a way to prevent fastclick from firing “active” state on scroll?

我在具有大鏈接的頁面上使用FastClick ,因為我想在移動瀏覽器中繞過300ms的點擊延遲。 我有一個“突出”樣式的鏈接' :active狀態,它正在快速正確觸發,感謝FastClick。

我的問題是 - 至少在Mobile Safari中 - 當你點擊和滑動以滾動頁面時它也會觸發。 這使得您覺得無法在不考慮點擊鏈接的情況下滾動頁面。

當有人滾動時,有沒有辦法阻止它發射?

也許你可以將needsclick類添加到正文中?

<body class="needsclick">

...

</body>

只是一個想法:)

好問題! +1

此問題與FastClick無關,但FastClick確實使您的問題的解決方案更加復雜。 所以我將堅持純JavaScript和原始觸摸事件)

在移動觸摸設備上,由於特定於平台的原因,webview的實現與桌面web瀏覽器顯着不同。 在這種情況下,一個重要的功能是webview中的動量滾動。 Momentum Scrolling是設備的硬件加速功能。 因此,當在屏幕上觸摸可滾動區域時,硬件識別觸摸並將200毫秒倒數計時器附加到可滾動區域,當觸發時,將該區域置於硬件加速滾動中。 當硬件處於狀態時,它不會廣播觸摸事件,因為它們特定於硬件加速滾動。 可以取消計時器,並通過在提供的200毫秒內對觸摸事件使用preventDefault來防止動量滾動。

這是我如何處理這個問題。 我假設您正在使用本機滾動即overflow:scroll 該方法是將touchstart事件附加到您想要可觸摸的元素。 touchstart事件觸發后,事件處理程序touchendtouchmovetouchcancel事件附加到目標元素。 啟動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發送觸摸事件200ms。

然后,要將事件附加到元素或元素集合,請使用:

tapify(document.querySelectorAll('button'), function (e) {
      //your event handler here!! 
});

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM