Mobile Safari – Le slider d'input ne défile pas avec le défilement à débordement: touchez

Je sais que Mobile Safari ne triggersra pas d'events en mode "impulsion" (-webkit-overflow-scrolling: touch;). Mais ce n'est pas tout à fait la même chose, car Safari gère le slider (clignotant) d'une input en interne.

<div id="container"> <input type="text" /> <div class="filling"></div> </div> #container { position: absolute; top: 20px; bottom: 20px; width: 50%; -webkit-overflow-scrolling: touch; overflow-y: auto; border: 1px solid black; } input { margin-top: 60vh; } .filling { height: 200vh; } 

Essayez ce violon sur votre appareil (concentrez l'input, puis faites défiler): https://jsfiddle.net/gabrielmaldi/n5pgedzv

Le problème se produit également lorsque vous maintenez votre doigt appuyé (c'est-à-dire non seulement lorsque vous lui donnez de l'élan et libérez): le slider ne défile pas.

Évidemment, je ne veux pas désactiver le défilement à débordement, s'il n'y a pas moyen de corriger le slider afin qu'il défile correctement, il serait correct de le cacher.

Merci

C'est en effet un bug WebKit et il semble qu'il n'y ait pas de solution de contournement connue.

@cvrebert a déposé le bogue:

Une seule solution de contournement que j'ai été trouvé – sur l'événement de défilement pour vérifier si l'input avec le text de type est mise au point, définir le focus sur un autre élément (par exemple, sur le button). En conséquence, le keyboard virtuel et le slider disparaîtront. Cette solution n'est pas parfaite, mais elle n'a pas l'air aussi horrible qu'avec des sliders au-dessus du formulaire. Exemple:

 $(".scrollContainer").scroll(function () { var selected = $("input[type='text']:focus"); if (selected.length > 0) { $('#someButton').focus(); } } 

Avait ce même problème, ma solution changeait entre

-webkit-overflow-scrolling: touch

et

 -webkit-overflow-scrolling: auto 

chaque fois que je me concentre / flou sur les inputs

J'ai passé beaucoup de time à essayer de comprendre cela, et n'ai pas eu de succès avec les autres idées mentionnées ici.

Une chose que j'ai remarquée est que même si le slider flotterait en dehors de l'input, une fois que vous commencez à taper sur le keyboard à l'écran, le slider revient dans la bonne position.

Cela m'a donné l'idée – peut-être en utilisant un code JS, je pourrais changer la valeur de l'input, puis rapidement revenir à la valeur actuelle. Peut-être que cela amènerait le slider à s'aligner exactement comme lorsque vous tapez manuellement.

Je l'ai testé et ça a marché. Voici à quoi ressemble le code:

  myIScroll.scrollToElement(element, scrollTime); // any scroll method call var scrollTime = 400; if (element.type && element.type == 'text') { var currentValue = $(element).val(); $timeout(function(){ $(element).val(currentValue + 'a').val(currentValue); }, scrollTime); } 

Vous pouvez résoudre le problème en supprimant la sélection et en la réinitialisant. Utiliser jQuery ici est le Javascript pour le faire. J'ajoute le gestionnaire d'events en entrant en mode d'édition:

  $(document).on('scroll.inline-edit', function(event) { var selection = window.getSelection(); if (selection.rangeCount) { var range = selection.getRangeAt(0); selection.removeAllRanges(); selection.addRange(range); } }); 

Lorsque je quitte le mode édition, je supprime le gestionnaire d'events:

  $(document).off('scroll.inline-edit'); 

Cela fonctionnera probablement aussi si le gestionnaire d'events est toujours activé.

C'est en effet un bug sur iOS 11. J'ai résolu le problème sur modal en changeant le css:

 .modal { position:fixed; overflow-y: scroll; bottom: 0; left: 0; right: 0; top: 0; z-index: 99; } body { height: 100%; width:100%; overflow: hidden; position:fixed; } 

J'utilise jQuery.animate pour faire défiler la window et je ne sais pas si cela fonctionnera si vous n'utilisez pas jQuery.animate, mais cela a fonctionné pour moi. Je ne fais que triggersr les gestionnaires "flous" sur l'élément, ce qui ne fait pas perdre de focus à l'élément, il triggers juste les gestionnaires comme s'ils avaient été déclenchés naturellement par l'interaction de l'user. Il semble :

 $content.animate( { scrollTop: $(this).data('originalTop') }, { duration: 100, easing: 'swing', always: function(){ var $t = $(this); $t.sortinggger('blur'); } } ); 

En raison d'autres bizarreries avec iOS, je dois sauvegarder la valeur supérieure offset (). De l'élément comme originalTop lorsque mon formulaire se charge. $ content est simplement une div scrollable contenant ma forme – par exemple: $ ('div # content').

Cela semble toujours déranger les formulaires webkit dans iOS avec -webkit-overflow-scrolling:touch , également dans iOS 11. Basé sur les réponses ci-dessus, et puisqu'il faut mettre au point un élément input ou textarea pour que le caret apparaisse à sa place, voici ma propre approche "corrigeant" pour cela

 $('input').on("focus", function(){ var scrollTopVal = $(elementSelector).scrollTop(); $(elementSelector).scrollTop(scrollTopVal + 1); $(elementSelector).scrollTop(scrollTopVal); }) 

elementSelector pointe vers l'élément conteneur pour les éléments d'input.