Есть ли способ предотвратить быстрый щелчок от включения "активного" состояния в свитке?

Im использует FastClick на странице с большими ссылками, потому что я хочу обойти 300 мс задержки для кранов в мобильных браузерах. У меня есть стиль "подсветки" для состояний ссылок :active, и он быстро срабатывает, благодаря FastClick.

Моя проблема заключается в том, что, по крайней мере, в Mobile Safari - она ​​также срабатывает, когда вы нажимаете и прокручиваете, чтобы прокручивать страницу. Это заставляет чувствовать, что вы не можете прокручивать страницу, не думая, что пытаетесь использовать ссылки.

Есть ли способ предотвратить его стрельбу, когда кто-то прокручивается?

Ответы

Ответ 1

Может быть, вы можете добавить класс needsclick в тело?

<body class="needsclick">

...

</body>

Просто идея:)

Ответ 2

Хороший вопрос! +1

Эта проблема не имеет ничего общего с FastClick, но FastClick делает решение вашей проблемы более сложным. Поэтому я буду придерживаться чистого JavaScript и сырых событий Touch)

На мобильном сенсорном устройстве реализация webview существенно отличается от веб-браузера на рабочем столе по причинам, характерным для платформы. Одна важная особенность в этом случае - прокрутка импульса в веб-просмотре. Momentum Scrolling - это аппаратная ускоренная функция устройства. Поэтому, когда область прокручиваемого экрана коснется экрана, аппаратное обеспечение идентифицирует касание и подключает таймер обратного отсчета 200 миллисекунд к области прокрутки, которая при запуске помещает область в аппаратную ускоренную прокрутку. Когда аппаратное обеспечение находится в состоянии, оно не передает события касания, поскольку они относятся к аппаратной ускоренной прокрутке. Таймер может быть отменен, а прокрутка по импульсу предотвращена с помощью preventDefault на сенсорном событии в течение 200 миллисекунд.

Вот как я подхожу к этой проблеме. Я предполагаю, что вы используете собственный scroll i.e overflow:scroll. Метод состоит в том, чтобы прикрепить событие touchstart к элементу, который вы хотите осязать. После того как событие touchstart запущено, обработчик события присоединяет события touchend, touchmove и touchcancel к целевому элементу. Вызывается таймер setTimout, который удаляет вновь добавленные события после 140 мс.

Вот несколько клипов для моего кода: У меня есть два метода событий для добавления и удаления событий из коллекций:

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 перестает отправлять события касания к веб-просмотру 200 мс.

Затем, чтобы прикрепить событие к элементу или набору элементов, используйте:

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

Надеюсь, что это поможет