developer debugger debug code chrome javascript ios css safari ios10

javascript - debugger - iOS 10 Safari: evita el desplazamiento detrás de una superposición fija y mantiene la posición de desplazamiento



safari developer (7)

No puedo evitar que el contenido del cuerpo principal se desplace mientras se muestra una superposición de posición fija. Muchas veces se hicieron preguntas similares, pero todas las técnicas que funcionaron anteriormente no parecen funcionar en Safari en iOS 10. Esto parece ser un problema reciente.

Algunas notas:

  • Puedo deshabilitar el desplazamiento si configuro tanto el html como el body para que se overflow: hidden , sin embargo, eso hace que el contenido del cuerpo se desplace hacia la parte superior.
  • Si el contenido de la superposición es lo suficientemente largo como para que pueda desplazarse, el desplazamiento se desactiva correctamente para el contenido de la página principal. Si el contenido de la superposición no es lo suficientemente largo como para provocar el desplazamiento, puede desplazarse por el contenido de la página principal.
  • touchmove una función javascript de http://blog.christoffer.me/six-things-i-learnt-about-ios-safaris-rubber-band-scrolling/ que desactiva el touchmove mientras se muestra la superposición. Esto funcionó anteriormente, pero ya no funciona.

Aquí está la fuente HTML completa:

<!doctype html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <style type="text/css"> html, body { width: 100%; height: 100%; margin: 0; padding: 0; } body { font-family: arial; } #overlay { display: none; position: fixed; z-index: 9999; left: 0; right: 0; top: 0; bottom: 0; overflow: scroll; color: #fff; background: rgba(0, 0, 0, 0.5); } #overlay span { position: absolute; display: block; right: 10px; top: 10px; font-weight: bold; font-size: 44px; cursor: pointer; } #overlay p { display: block; padding: 100px; font-size: 36px; } #page { width: 100%; height: 100%; } a { font-weight: bold; color: blue; } </style> <script> $(function() { $(''a'').click(function(e) { e.preventDefault(); $(''body'').css(''overflow'', ''hidden''); $(''#page'').addClass(''disable-scrolling''); // for touchmove technique below $(''#overlay'').fadeIn(); }); $(''#overlay span'').click(function() { $(''body'').css(''overflow'', ''auto''); $(''#page'').removeClass(''disable-scrolling''); // for touchmove technique below $(''#overlay'').fadeOut(); }); }); /* Technique from http://blog.christoffer.me/six-things-i-learnt-about-ios-safaris-rubber-band-scrolling/ */ document.ontouchmove = function ( event ) { var isTouchMoveAllowed = true, target = event.target; while ( target !== null ) { if ( target.classList && target.classList.contains( ''disable-scrolling'' ) ) { isTouchMoveAllowed = false; break; } target = target.parentNode; } if ( !isTouchMoveAllowed ) { event.preventDefault(); } }; </script> </head> <body> <div id="overlay"> <span>&times;</span> <p>fixed popover</p> </div> <div id="page"> <strong>this is the top</strong><br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> lots of scrollable content<br> asdfasdf<br> <br> <div><a href="#">Show Popover</a></div> <br> <br> </div> </body> </html>



Cuando se abre la superposición, puede agregar una clase como prevent-scroll al body para evitar el desplazamiento de los elementos detrás de la superposición:

body.prevent-scroll { position: fixed; overflow: hidden; width: 100%; height: 100%; }

https://codepen.io/claudiojs/pen/ZKeLvq


Encontré el código en github . Funciona en Safari en iOS 10,11,12.

/* ScrollClass */ class ScrollClass { constructor () { this.$body = $(''body''); this.styles = { disabled: { ''height'': ''100%'', ''overflow'': ''hidden'', }, enabled: { ''height'': '''', ''overflow'': '''', } }; } disable ($element = $(window)) { let disabled = false; let scrollTop = window.pageYOffset; $element .on(''scroll.disablescroll'', (event) => { event.preventDefault(); this.$body.css(this.styles.disabled); window.scrollTo(0, scrollTop); return false; }) .on(''touchstart.disablescroll'', () => { disabled = true; }) .on(''touchmove.disablescroll'', (event) => { if (disabled) { event.preventDefault(); } }) .on(''touchend.disablescroll'', () => { disabled = false; }); } enable ($element = $(window)) { $element.off(''.disablescroll''); this.$body.css(this.styles.enabled); } }

utilizar:

Scroll = new ScrollClass(); Scroll.disable();// disable scroll for $(window) Scroll.disable($(''element''));// disable scroll for $(''element'') Scroll.enable();// enable scroll for $(window) Scroll.enable($(''element''));// enable scroll for $(''element'')

Espero que te ayude.


Intenté encontrar una solución limpia a esto durante mucho tiempo, y lo que parece que me ha funcionado mejor es establecer pointer-events: none; en el cuerpo, y luego pointer-events: auto; explícitamente en el elemento que quiero permitir el desplazamiento en.


Para aquellos que usan React, he tenido éxito al poner la solución de @ bohdan-didukh en el método componentDidMount en un componente. Algo como esto (enlace visible a través de navegadores móviles):

class Hello extends React.Component { componentDidMount = () => { var _overlay = document.getElementById(''overlay''); var _clientY = null; // remember Y position on touch start function isOverlayTotallyScrolled() { // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions return _overlay.scrollHeight - _overlay.scrollTop <= _overlay.clientHeight; } function disableRubberBand(event) { var clientY = event.targetTouches[0].clientY - _clientY; if (_overlay.scrollTop === 0 && clientY > 0) { // element is at the top of its scroll event.preventDefault(); } if (isOverlayTotallyScrolled() && clientY < 0) { //element is at the top of its scroll event.preventDefault(); } } _overlay.addEventListener(''touchstart'', function (event) { if (event.targetTouches.length === 1) { // detect single touch _clientY = event.targetTouches[0].clientY; } }, false); _overlay.addEventListener(''touchmove'', function (event) { if (event.targetTouches.length === 1) { // detect single touch disableRubberBand(event); } }, false); } render() { // border and padding just to illustrate outer scrolling disabled // when scrolling in overlay, and enabled when scrolling in outer // area return <div style={{ border: "1px solid red", padding: "48px" }}> <div id=''overlay'' style={{ border: "1px solid black", overflowScrolling: ''touch'', WebkitOverflowScrolling: ''touch'' }}> {[...Array(10).keys()].map(x => <p>Text</p>)} </div> </div>; } } ReactDOM.render( <Hello name="World" />, document.getElementById(''container'') );

Visible a través del móvil: https://jsbin.com/wiholabuka

Enlace editable: https://jsbin.com/wiholabuka/edit?html,js,output


Trate de agregar a la altura máxima del cuerpo: 100vh;



por favor, agregue -webkit-overflow-scrolling: touch; al elemento #overlay .

Y agregue por favor este código javascript al final de la etiqueta del cuerpo:

(function () { var _overlay = document.getElementById(''overlay''); var _clientY = null; // remember Y position on touch start _overlay.addEventListener(''touchstart'', function (event) { if (event.targetTouches.length === 1) { // detect single touch _clientY = event.targetTouches[0].clientY; } }, false); _overlay.addEventListener(''touchmove'', function (event) { if (event.targetTouches.length === 1) { // detect single touch disableRubberBand(event); } }, false); function disableRubberBand(event) { var clientY = event.targetTouches[0].clientY - _clientY; if (_overlay.scrollTop === 0 && clientY > 0) { // element is at the top of its scroll event.preventDefault(); } if (isOverlayTotallyScrolled() && clientY < 0) { //element is at the top of its scroll event.preventDefault(); } } function isOverlayTotallyScrolled() { // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions return _overlay.scrollHeight - _overlay.scrollTop <= _overlay.clientHeight; } }())

Espero que te ayude.