Nizza domanda! +1
Questo problema non ha nulla a che fare con FastClick, ma FastClick rende la soluzione al tuo problema più complessa. Quindi mi limiterò a puro JavaScript e Raw Touch Events)
Su un dispositivo mobile touch l'implementazione della webview è significativamente diversa dal browser web desktop per ragioni specifiche della piattaforma. Una funzione importante in questo caso è lo scorrimento del momento nella visualizzazione Web. Lo scorrimento del momento è una funzione hardware accelerata del dispositivo. Quindi, quando un'area sensibile viene toccata sullo schermo, l'hardware identifica il tocco e allega un timer per il conto alla rovescia di 200 millisecondi all'area scorrevole, che, una volta attivato, inserisce l'area in una scroll accelerata hardware. Quando l'hardware è nello stato, non trasmette eventi touch perché sono specifici per lo scorrimento accelerato hardware. Il timer può essere annullato e lo scorrimento del momento evitato utilizzando preventDefault sull'evento di tocco entro 200 millisecondi previsti.
Ecco come approccio a questo problema. Presumo che tu stia usando la scroll nativa i.e overflow:scroll
. Il metodo consiste nel collegare un evento touchstart
all'elemento che si desidera toccare. Dopo l'attivazione dell'evento touchstart
, il gestore eventi allega gli eventi touchend
, e touchcancel
all'elemento di destinazione. Viene avviato un timer setTimout che rimuove gli eventi appena aggiunti dopo 140 ms.
Ecco alcune clip per il mio codice di produzione: ho due metodi di eventi per l'aggiunta e la rimozione di eventi da collezioni:
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
})();
Poi Ho un metodo tapify per gli eventi rubinetto sul scroller:
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;
})();
Uso global.isIos per identificare il dispositivo di destinazione. Android interrompe l'invio di eventi di tocco a webview fino a 200ms.
Poi per fissare l'evento a un elemento o un insieme di elementi, utilizzare:
tapify(document.querySelectorAll('button'), function (e) {
//your event handler here!!
});
Spero che questo aiuti
Grazie ... che sarebbe effettivamente impedire FastClick di lavorare per i controlli a tutti. –