web-dev-qa-db-fra.com

Position de défilement actuelle lors de l’utilisation de -webkit-overflow-scrolling: touch - événement JavaScript Safari iOS (scrollTop/scrollLeft)

J'utilise -webkit-overflow-scrolling: appuyez pour créer une div avec débordement: scroll; faites défiler en douceur les événements tactiles iOS.

Cela fonctionne brillamment, sauf qu'il ne semble pas mettre à jour element.scrollTop ou element.scrollLeft pendant le défilement. Il met à jour uniquement element.scrollTop/déclenche un événement de défilement lorsque le momentum est écoulé et qu'il s'arrête.

Est-ce que quelqu'un connaît un moyen de connaître sa position actuelle de défilement et s'il y a un événement que je peux écouter? Je me demandais si on pouvait le trouver via une propriété CSS3 peut-être? Merci

Exemple ci-dessous montrant deux tentatives:

<!DOCTYPE html>
<body>
    <div id="display_a">Scroll is: 0</div>
    <div id="display_b">Scroll is: 0</div>  
    <div id="element" style="width:800px;overflow-x:scroll;-webkit-overflow-scrolling:touch;">
        <div style="font-size:100px;width:1850px;">
            a b c d e f g h i j k l m n o p q r s t u v w x y z
        </div>
    </div>
    <script>
        var e = document.getElementById("element");
        var display_a = document.getElementById("display_a");
        var display_b = document.getElementById("display_b");
        e.addEventListener("scroll",function(event){display_a.innerHTML = "Scroll is: " + event.target.scrollLeft;});
        setInterval(function(){display_b.innerHTML = "Scroll is: " +  e.scrollLeft;},100);
    </script>   
</body>
</html>

============ UPDATE ============

iOS 8 a résolu ce problème. Les événements de défilement sont maintenant déclenchés lors du défilement.

Notez que vous devrez maintenant gérer les valeurs de défilement négatives lors du défilement du rebond.

26
Jamie G

La bibliothèque de développement iOS contient une explication à ce sujet dans les instructions de Safari: 

http://developer.Apple.com/library/IOs/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html

En gros, le déroulement des événements pour le défilement se déroule comme suit: Toucher/commencer à faire glisser (événement molette) -> panoramique/mouvement (aucun événement) -> arrêt (onscroll)

Il n'y a donc rien de tel qu'un événement continu de défilement étant déclenché alors que le panoramique se produit, il y a juste un onScroll à la fin du geste. 

Si vous trouvez un moyen facultatif d'y parvenir, faites-le moi savoir :)

10
pixshatterer

Cela pourrait aider. C’est une solution jQuery que j’utilise pour forcer la pagination sur IOS balayer d’un côté à l’autre. Ce n'est pas exactement le même cas que vous travaillez. J'utilise le "débordement-défilement: auto" qui ne se comporte pas comme la version "tactile".

#yourDiv {
    -webkit-overflow-scrolling: auto;
    overflow:auto;
}

J'utilise "overflow-scrolling: auto" car il réagit plus rapidement à l'événement touchend. Malheureusement, "overflow-scrolling: touch" semble en effet résister aux animations javascript et CSS en mouvement. Mais au moins, vous pouvez obtenir des informations de localisation pendant le défilement.

var pageSwiping = false;

$('#yourDiv').on('scroll', function(e) {
    if (pageSwiping !== true  ) {
        pageSwiping = true;
        var offset = $('#'+e.target.id).scrollLeft();
        $('#yourDiv').one( 'touchend',{elem:e.target.id,dragStart:offset},divMove);
    };
});

var divMove = function(e) {
    pageSwiping = false;
    var elem = e.data.elem;
    var dragEnd = $('#'+elem).scrollLeft();
    var dragDelta = (dragEnd - e.data.dragStart)
        // Make page-alignment decisions based on dragDelta
};
2
mattsahr

Dans une situation similaire, j'utilise scrollability.js , qui fait un travail vraiment sympa en simulant le comportement de défilement natif. J'écoute ensuite l'événement 'scrollability-start' et surveille les attributs haut/gauche de l'élément défilé. Je sais que ce n'est pas idéal, mais c'est une alternative décente.

2
spacehelmetboy

Voici mon référentiel dans lequel j'ai ajouté le callback onScrolling() pour me faire savoir quand l'animation défile par moment se produit dans animate(): https://github.com/simpleshadow/iscroll/blob/master/src/iscroll.js

J'ai créé un exemple d'application en utilisant sa suggestion ici: http://jsfiddle.net/simpleshadow/wQQEM/22/

@ robertlawson86 sur Github a fait cette suggestion pour aider à donner une idée du moment où saisir la position lors du défilement de momentum. Voir exemple et discussion: https://github.com/cubiq/iscroll/issues/183

1
Corey

Je sais que c'est bizarre, mais vous pouvez garder une trace de scrollLeft/scrollTop simplement en enregistrant un événement touchstart:

e.addEventListener("touchstart",function(event){});
0
David

Obtenir la position d'un scroller horizontal en cours de rouleau (via css overflow-y: scroll) 

$('#myNode').bind('scroll', function(e){
  var myPos = e.target.scrollLeft;
  // do something with myPos but don't naughty
})
0
flunder