lince veloz
El problema:
Sé que esta pregunta se ha hecho una docena de veces, pero ninguna de las soluciones a esas preguntas funcionó para mí.
Quiero que el elemento del cuerpo en iOS 13 Safari no se desplace. Esto significa que no hay desplazamiento ni efecto de rebote elástico (desbordamiento-desplazamiento).
Tengo dos elementos uno al lado del otro en los que he establecido overflow: scroll;
esos deberían desplazarse, solo el cuerpo que los rodea no debería.
Todas las soluciones que probé simplemente no funcionan en aplicaciones web progresivas que tienen la siguiente etiqueta dentro de su cabeza y se guardan en la pantalla de inicio.
<meta name="apple-mobile-web-app-capable" content="yes">
Soluciones que he probado:
prueba 1: configuración de desbordamiento oculto en el cuerpo y/o html. No funcionó para iOS 13 safari.
https://stackoverflow.com/a/18037511/10551293
html {
position: relative;
overflow: hidden;
height: 100%;
}
body {
position: relative;
overflow: hidden;
height: 100%;
}
no hace nada en iOS 13 safari pero funciona en macOS safari y Firefox.
prueba 2: posición de ajuste fijada en el cuerpo. No funciona para mí porque cuando el usuario se desplaza, el cuerpo no lo hace, pero el desplazamiento aún evita que mis dos elementos internos se desplacen mientras se anima el rebote de desbordamiento.
https://stackoverflow.com/a/47874599/10551293
body {
position: fixed;
}
solo pone el cuerpo sobre el desplazamiento de la página. El desplazamiento (overflow-scrolling) ocurre a través del cuerpo fijo…
prueba 3: evitando que se mueva el valor predeterminado al tocar. No funcionó (es una solución más antigua…).
https://stackoverflow.com/a/49853392/10551293
document.addEventListener("touchmove", function (e) {
e.preventDefault();
}, { passive: false });
No hace nada por lo que puedo decir. Ni en safari ni en Firefox.
prueba 4: evitando el desplazamiento predeterminado de la ventana y volviendo a establecer la posición de desplazamiento en 0. No es viable debido a las animaciones con errores.
window.addEventListener("scroll", (e) => {
e.preventDefault();
window.scrollTo(0, 0);
});
establece la posición de desplazamiento de nuevo en 0, pero el desplazamiento de desbordamiento aún se aplica, lo que termina en un comportamiento defectuoso.
Un fragmento que lo demuestra:
Para probarlo usted mismo, guarde el fragmento a continuación como un archivo html y guárdelo en la pantalla de inicio de un iPad (o simulador de iPad). El cuerpo de repente se vuelve desplazable cuando se guarda en la pantalla de inicio.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<meta name="apple-mobile-web-app-capable" content="yes">
</head>
<body>
<style>
body, html {
position: relative;
overflow: hidden;
height: 100%;
width: 100%;
}
body {
margin: 0;
display: flex;
flex-direction: column;
}
nav, footer {
width: 100%;
height: 5rem;
background: blue;
flex-shrink: 0;
}
main {
display: flex;
height: 0;
flex-grow: 1;
padding: 2rem;
}
section {
width: 50%;
overflow: scroll;
display: flex;
flex-direction: column;
align-items: center;
}
div {
flex-shrink: 0;
width: 25%;
height: 18rem;
margin: 1rem;
background: red;
}
</style>
<nav></nav>
<main>
<section>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
<section>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
</main>
<footer></footer>
</body>
</html>
Ninguno de ellos funcionó de manera aceptable para mí, ahora, ¿cómo hago esto para que funcione correctamente en iOS 13 Safari (cuando se guarda como PWA en la pantalla de inicio)?
Combiné el intento 2 y el intento 4 de la pregunta. El cuerpo fijo no muestra desplazamiento de desbordamiento y el reinicio de desplazamiento evita la animación larga del desplazamiento de desbordamiento en segundo plano. Es muy feo pero funciona un poco.
body {
position: fixed;
}
window.addEventListener("scroll", (e) => {
e.preventDefault();
window.scrollTo(0, 0);
});
-
Necesitaba completo:
body {position: fixed; left: 0; top: 0; right: 0; bottom: 0;}
– zbycz
26 jun 2021 a las 10:30
-
Esta es una muy buena respuesta. Esto ayuda mucho
– liangdapang
27 de junio de 2022 a las 6:53
blallo
function unlockScroll () {
const scrollY = this.body.style.top;
document.body.style.position = '';
document.body.style.top = '';
document.body.style.left="";
document.body.style.right="";
window.scrollTo(0, parseInt(scrollY || '0') * -1);
};
function lockScroll () {
document.body.style.position = 'fixed';
document.body.style.top = `-${window.scrollY}px`;
document.body.style.left="0";
document.body.style.right="0";
};
-
Esto también bloquea el desplazamiento en mis dos elementos internos.
– lince veloz
11 de diciembre de 2019 a las 12:31
-
confirmo esta respuesta
– Kamran Asgari
17 de julio de 2020 a las 14:34
-
@swiftlynx, ¿pusiste desbordamiento en tus elementos internos?
– Blallo
22 de julio de 2020 a las 10:47
-
Esto funciona tanto en Android 10 (Chrome) como en iOS 13.7 (Safari). ¡Mil millones de gracias!
– Mirós
1 oct 2020 a las 19:39
-
Para todos los que todavía necesitan esto, puse una versión mejorada disponible en github con licencia MIT e incluso un paquete npm: github.com/8lall0/cuerpo-bloqueo. Esto tiene en cuenta el desbordamiento vertical y horizontal, y mantiene las barras de desplazamiento para evitar el “salto” que puede tener una página si elimina la barra de desplazamiento, además agrega una clase al cuerpo si necesita un estilo adicional cuando bloquea el cuerpo.
– Blallo
18 oct 2021 a las 10:07
En mi caso (la aplicación requiere arrastrar para organizar los elementos) configuración acción táctil a none
funcionó para evitar el desplazamiento al arrastrar ciertos elementos.
p.ej
draggableElement.css('touch-action', 'none') // disable actions
draggableElement.css('touch-action', 'auto') // restore actions
Simplemente agregue una acción táctil: ninguna al cuerpo en CSS:
body{
touch-action:none;
}
https://github.com/willmcpo/cuerpo-desplazamiento-bloqueo
No puedo probarlo en este momento, pero parece que vale la pena intentarlo.
Petrolea
Tuve un problema similar antes y hasta ahora, usar el siguiente enfoque ha funcionado mejor:
-
primero, habilite el desplazamiento en su contenedor de contenido aplicando
-webkit-overflow-scrolling: touch
-
en segundo lugar, aplicar las siguientes reglas:
/* this part makes sure there is nowhere left to scroll */
html {
position: static;
overflow-y: hidden;
height: 100%;
max-height: 100%;
}
/* all properties don't necessarily need to be applied on both elements,
this is only used to override any existing code */
body {
overflow: hidden;
height: 100%;
max-height: 100%;
}
window.addEventListener('touchend', _ => {
window.scrollTo(0,0)
});
Esto hará que el cuerpo vuelva a 0,0 después de que el usuario suelte el cuerpo, lo que le permitirá desplazarse inmediatamente hacia abajo sin animaciones extrañas, además de regresar de inmediato. Lo probé con una animación de desplazamiento suave, pero no siempre anima lo suficientemente rápido. Esto evitará el bloqueo de pantalla que ocurre cuando el cuerpo se desplaza desde el desplazamiento elástico de rebote en ese iPhone y solo se activa cuando el usuario suelta el tirón.
Creo que necesita establecer una altura fija para que el desbordamiento oculto funcione, así:
html { position: relative; overflow: hidden; height: 90vh; }
–Anshul Gupta
5 de diciembre de 2019 a las 11:58
Tampoco funcionó, yo también lo he intentado…
– lince veloz
5 de diciembre de 2019 a las 12:59
¿Puedes agregar un violín o algo así para obtener una vista previa de los elementos? No puedo crear imágenes de tus elementos.
–Anshul Gupta
5 de diciembre de 2019 a las 13:07
No estaba claro en mi pregunta, solo no funciona cuando la página se guarda como una aplicación web en la pantalla de inicio y si tiene la siguiente metaetiqueta:
– lince veloz
5 de diciembre de 2019 a las 13:24
Y agregué un fragmento de código.
– lince veloz
5 de diciembre de 2019 a las 13:31