web-dev-qa-db-fra.com

événement de défilement javascript pour iPhone / iPad?

Je n'arrive pas à capturer l'événement de défilement sur un iPad. Aucun de ces travaux, ce que je fais mal?

window.onscroll=myFunction;

document.onscroll=myFunction;

window.attachEvent("scroll",myFunction,false);

document.attachEvent("scroll",myFunction,false);

Ils fonctionnent tous même sur Safari 3 sous Windows. Paradoxalement, CHAQUE navigateur sur le PC prend en charge window.onload= si le fait de ne pas déranger les événements existants ne vous dérange pas. Mais non, allez sur iPad.

105
ck_

L'iPhoneOS capture les événements onscroll, sauf ce que vous attendez.

Le panoramique à un doigt ne génère aucun événement tant que l'utilisateur ne l'a pas arrêté (un événement onscroll est généré lorsque la page cesse de se déplacer et se redessine), comme illustré à la figure 6-1.

De même, le défilement avec 2 doigts déclenche onscroll seulement après que vous avez arrêté de faire défiler.

La manière habituelle d’installer le gestionnaire fonctionne, par exemple:.

window.addEventListener('scroll', function() { alert("Scrolled"); });
// or
$(window).scroll(function() { alert("Scrolled"); });
// or
window.onscroll = function() { alert("Scrolled"); };
// etc 

(Voir aussi https://developer.Apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html )

140
kennytm

Pour iOS, vous devez utiliser l'événement touchmove ainsi que l'événement scroll comme ceci:

document.addEventListener("touchmove", ScrollStart, false);
document.addEventListener("scroll", Scroll, false);

function ScrollStart() {
    //start of scroll event for iOS
}

function Scroll() {
    //end of scroll event for iOS
    //and
    //start/end of scroll event for other browsers
}
103
George Filippakos

Désolé d’ajouter une autre réponse à un ancien message, mais j’obtiens très bien un événement de défilement en utilisant ce code (il fonctionne au moins sur la version 6.1)

element.addEventListener('scroll', function() {
    console.log(this.scrollTop);
});

// This is the magic, this gives me "live" scroll events
element.addEventListener('gesturechange', function() {});

Et ça marche pour moi. La seule chose qu’il ne fait pas, c’est de donner un événement de défilement pour la décélération du défilement (une fois la décélération terminée, vous obtenez un dernier événement de défilement, faites ce que vous voulez.) Mais si vous désactivez l’inertie avec css en procédant de la sorte

-webkit-overflow-scrolling: none;

Vous n'obtenez pas d'inertie sur vos éléments, pour le corps même si vous devez faire le classique

document.addEventListener('touchmove', function(e) {e.preventDefault();}, true);
36
Dave Mackintosh

J'ai réussi à trouver une excellente solution à ce problème avec iScroll, avec l'impression de défiler sur un momentum et tout https://github.com/cubiq/iscroll Le doc github est génial et j'ai surtout suivi il. Voici les détails de ma mise en œuvre.

HTML: J'ai enveloppé la zone de défilement de mon contenu dans certains div que iScroll peut utiliser:

<div id="wrapper">
  <div id="scroller">
    ... my scrollable content
  </div>
</div>

CSS: J'ai utilisé la classe Modernizr pour "touch" pour cibler mes modifications de style uniquement sur les périphériques tactiles (car je n'ai instancié que iScroll).

.touch #wrapper {
  position: absolute;
  z-index: 1;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  overflow: hidden;
}
.touch #scroller {
  position: absolute;
  z-index: 1;
  width: 100%;
}

JS: J'ai inclus iscroll-probe.js à partir du téléchargement iScroll, puis initialisé le défilement comme ci-dessous, où updatePosition est ma fonction qui réagit à la nouvelle position de défilement.

# coffeescript
if Modernizr.touch
  myScroller = new IScroll('#wrapper', probeType: 3)
  myScroller.on 'scroll', updatePosition
  myScroller.on 'scrollEnd', updatePosition

Vous devez utiliser myScroller pour obtenir la position actuelle maintenant, au lieu de regarder le décalage de défilement. Voici une fonction tirée de http://markdalgleish.com/presentations/embracingtouch/ (un article très utile, mais un peu obsolète maintenant)

function getScroll(elem, iscroll) {   
  var x, y;

  if (Modernizr.touch && iscroll) {
    x = iscroll.x * -1;
    y = iscroll.y * -1;   
  } else {
    x = elem.scrollTop;
    y = elem.scrollLeft;   
  }

  return {x: x, y: y}; 
}

Le seul autre casse-tête était de temps en temps je perdais une partie de ma page à laquelle j'essayais de faire défiler, et elle refusait de faire défiler. Je devais ajouter quelques appels à myScroller.refresh () chaque fois que je changeais le contenu de #wrapper, ce qui résolvait le problème.

EDIT: Un autre piège était que iScroll mange tous les événements "click". J'ai activé l'option permettant à iScroll d'émettre un événement "tap" et de le gérer au lieu de "cliquer". Heureusement, je n'ai pas eu besoin de beaucoup cliquer dans la zone de défilement, donc ce n'était pas grave.

6
Melinda Weathers

Depuis qu'iOS 8 est sorti, ce problème n'existe plus. L'événement de défilement est maintenant bien déclenché dans iOS Safari également.

Donc, si vous enregistrez le gestionnaire d'événement scroll et que vous vérifiez window.pageYOffset à l'intérieur de ce gestionnaire d'événements, tout fonctionne correctement.

1
Matthias Bohlen