Ответ 1
Может быть, вы можете добавить класс needsclick
в тело?
<body class="needsclick">
...
</body>
Просто идея:)
Im использует FastClick на странице с большими ссылками, потому что я хочу обойти 300 мс задержки для кранов в мобильных браузерах. У меня есть стиль "подсветки" для состояний ссылок :active
, и он быстро срабатывает, благодаря FastClick.
Моя проблема заключается в том, что, по крайней мере, в Mobile Safari - она также срабатывает, когда вы нажимаете и прокручиваете, чтобы прокручивать страницу. Это заставляет чувствовать, что вы не можете прокручивать страницу, не думая, что пытаетесь использовать ссылки.
Есть ли способ предотвратить его стрельбу, когда кто-то прокручивается?
Может быть, вы можете добавить класс needsclick
в тело?
<body class="needsclick">
...
</body>
Просто идея:)
Хороший вопрос! +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!!
});
Надеюсь, что это поможет