2012-11-20 4 views
16

Wie entfernen Sie die Click/Tap-Verzögerung von Mobile Safari auf iOS?Speed ​​Fix: Wie entferne ich die 300ms Verzögerung in jQuery Mobile Apps

Ich habe mit Event-Listener ziemlich herumgespielt, und habe eine Reihe von verschiedenen Skripten (wie Lightning Touch) ohne Freude verwendet. Es gibt ein paar Lösungen, die funktionieren würden, aber diese Arten von Skripten zwingen Sie, ein Zielelement für jeden Link im DOM zu codieren. Dies kann leider einige schnelle und langsame Übergänge verursachen, die für mich nicht funktionieren.

Antwort

23

ich schließlich fand die Antwort auf meine Geschwindigkeit Weh nach unermüdlicher Suche, und es kommt in Form von Fastclick (this thread geht sehr ins Detail, zusammen mit einigen Verbesserungen in den Kommentaren von anderen Usern).

Integrieren Sie das FastClick.js-Skript, fügen Sie den onLoad-Listener hinzu und umhüllen Sie Ihren Inhalt mit <body> in einem Bereich, und Ihre App sollte sich viel nativer anfühlen.


Beiladen Zuhörer:<body onLoad="initFastButtons();">

Span-Verpackung:

<body onLoad="initFastButtons();"> 
    <span id="fastclick"> 

    [...] 

    </span> 
</body> 

FastClick.js

//======================================================== FASTCLICK 
     function FastButton(element, handler) { 
      this.element = element; 
      this.handler = handler; 
      element.addEventListener('touchstart', this, false); 
     }; 
     FastButton.prototype.handleEvent = function(event) { 
      switch (event.type) { 
       case 'touchstart': this.onTouchStart(event); break; 
       case 'touchmove': this.onTouchMove(event); break; 
       case 'touchend': this.onClick(event); break; 
       case 'click': this.onClick(event); break; 
      } 
     }; 
     FastButton.prototype.onTouchStart = function(event) { 

event.stopPropagation(); 
      this.element.addEventListener('touchend', this, false); 
      document.body.addEventListener('touchmove', this, false); 
      this.startX = event.touches[0].clientX; 
      this.startY = event.touches[0].clientY; 
isMoving = false; 
     }; 
     FastButton.prototype.onTouchMove = function(event) { 
      if(Math.abs(event.touches[0].clientX - this.startX) > 10 || Math.abs(event.touches[0].clientY - this.startY) > 10) { 
       this.reset(); 
      } 
     }; 
     FastButton.prototype.onClick = function(event) { 
      this.reset(); 
      this.handler(event); 
      if(event.type == 'touchend') { 
       preventGhostClick(this.startX, this.startY); 
      } 
     }; 
     FastButton.prototype.reset = function() { 
      this.element.removeEventListener('touchend', this, false); 
      document.body.removeEventListener('touchmove', this, false); 
     }; 
     function preventGhostClick(x, y) { 
      coordinates.push(x, y); 
      window.setTimeout(gpop, 2500); 
     }; 
     function gpop() { 
      coordinates.splice(0, 2); 
     }; 
     function gonClick(event) { 
      for(var i = 0; i < coordinates.length; i += 2) { 
       var x = coordinates[i]; 
       var y = coordinates[i + 1]; 
       if(Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) { 
        event.stopPropagation(); 
        event.preventDefault(); 
       } 
      } 
     }; 
     document.addEventListener('click', gonClick, true); 
     var coordinates = []; 
     function initFastButtons() { 
new FastButton(document.getElementById("fastclick"), goSomewhere); 
     }; 
     function goSomewhere() { 
var theTarget = document.elementFromPoint(this.startX, this.startY); 
if(theTarget.nodeType == 3) theTarget = theTarget.parentNode; 

var theEvent = document.createEvent('MouseEvents'); 
theEvent.initEvent('click', true, true); 
theTarget.dispatchEvent(theEvent); 
     }; 
//======================================================== 
+2

Hat jemand eine nicht js intensive Lösung gestoßen? Vielleicht mit css pointer-events: none; ? – JackMahoney

+1

fastclick ** vollständig ** scheitert mit jquery ziehbar – 8DK

0

Das funktioniert für mich. Jedes Mal, wenn eine neue Seite in der dom hinzugefügt haben, können wir dann schnell Klick auf alle Links anhängen ...

// when new pages are loaded into the DOM via JQM AJAX Nav, apply ko bindings to that page's DOM 
$(document).on('pageinit', '.ui-page', function (event, data) 
{ 
    var activePage = $(event.target).get(0); 
    FastClick.attach(activePage); 
}); 
0

Ben Howdle vor kurzem erstellt eine Open-Source-Projekt Touche.js, die dieses Problem in einer ziemlich einfache und elegante Art und Weise anspricht. Vielleicht lohnt sich ein Blick für jeden, der nach einer Lösung für dieses Problem sucht.

0

Ich bin nicht in der Lage, einen Kommentar direkt zu MikeZ Empfehlung zu posten.

Ich habe es erfolgreich verwendet, musste aber einige zusätzliche Tweek, vor allem für Android-Geräte.

Statt event.preventDefault(); in gonClick von() aufgerufen wird, hatte ich auch event.stopImmediatePropagation();

Ansonsten rufen Sie besonders in Schwierigkeiten geraten könnten, wenn dynamische Elemente, wie Platten, auf der Oberseite des Elements geöffnet Sie geklickt haben.

kompletter gonClick() -Methode mit MikeZ Lösung verwendet werden:

function gonClick(event) { 
    for (var i = 0; i < coordinates.length; i += 2) { 
     var x = coordinates[i]; 
     var y = coordinates[i + 1]; 
     if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) { 
      event.stopPropagation(); 
      event.preventDefault(); 
      event.stopImmediatePropagation(); 
     } 
    } 
};