Existe una técnica conocida para deshabilitar el desplazamiento de página cuando se abre la ventana modal.
CSS:
html {
height: 100%;
}
body.disable-scroll {
position: fixed;
height: 100%;
overflow: hidden;
}
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1.0, user-scalable=no" name="viewport">
</head>
<body class="disable-scroll">
<div class="page-content">
<input type="text">
... content ...
</div>
</body>
</html>
Pero en IOS Safari, el desplazamiento se habilita después de abrir el teclado virtual. Y se desplaza más que incluso window.innerHeight + window.scrollX
. Aparece un espacio en blanco en la parte inferior de la página.
URL del editor
https://codesandbox.io/s/condescending-snow-skuo5?fontsize=14
URL de pantalla completa para verificar en iPhone
https://skuo5.codesandbox.io/
Simplemente abra en iPhone o en XCode con IOS 12+ intente desplazarse y luego concéntrese en Entrada e intente desplazarse nuevamente.
Bolso Prajyot
Acabo de realizar una búsqueda tediosa y parece que es un problema con el iPhone, como ha señalado en el siguiente artículo: https://blog.opendigerati.com/the-excentric-ways-of-ios-safari-with-the-keyboard-b5aa3f34228d
Entonces, no hay forma de que puedas hacerlo con css seguro.
Pero eso no te impide usar JQuery y Javascript >:)
Aquí hay un trabajo desordenado para su escenario. He probado con múltiples cuadros de texto también solo en iPhone:
document.getElementById("app").innerHTML = `
<div class="page-content">
<input type="text"
onfocus="disableScrolling(this)"
onfocusout="enableScrolling(this)">
<p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p>
<input type="text"
id="text2"
onfocus="disableScrolling(this)"
onfocusout="enableScrolling(this)">
<p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p><p>Page content</p>
</div>`;
var currentElem;
function stopScroll()
{
if(currentElem)
{
var top = $("input:focus").offset().top;
$('html, body').stop().animate({
scrollTop: top
}, 500, function(){});
}
}
function disableScrolling(elem)
{
currentElem = elem;
document.addEventListener("touchend", stopScroll);
setTimeout(function()
{
stopScroll();
},10);
}
function enableScrolling()
{
currentElem = undefined;
document.removeEventListener("touchend", stopScroll);
}
html {
height: 100%;
scroll-behavior: smooth;
}
body.disable-scroll {
position: fixed;
height: 100%;
overflow: hidden;
}
.page-content {
background: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body class="disable-scroll">
<div id="app"></div>
<div>End of body</div>
</body>
Para explicar brevemente lo que hice.
Problema : El usuario puede alejarse mientras enfoca
textbox
Asumiendo que,
Solución : Permita que el usuario se desplace donde quiera y una vez que haya terminado, llévelo de regreso sin problemas a donde quiere que esté;
input:focused
:pag
Nota: he usado JQuery para simplificar las cosas. Si desea utilizar javascript puro, puede encontrar el reemplazo de los códigos específicos.
-
Gracias por su publicación, ¡es una buena idea volver a la entrada enfocada! Solo dos cosas: sería bueno agregar el código relevante en la respuesta misma, de esa manera la solución no desaparecerá cuando sus enlaces se desactiven. Además, no estoy muy seguro de por qué aconsejarías a la gente jQuery y no javascript vainilla. jQuery realmente ya no es necesario hoy en día.
– Stephan Müller
4 sep 2019 a las 19:42
-
Lolzz, soy un tipo de la vieja escuela: ppp, he trabajado mucho en JQuery en mis días iniciales y, por encima de todo, ¡también soy flojo>.$(“#target”); encima
document.getElementById("target");
(longitud de código más corta) 😉 JQuery simplemente simplifica la codificación 🙂 Consulte “CÓDIGO” en este sitio Sí, vanilla js puede hacer cosas, pero se complica muchas veces con un código enorme. como conseguiroffset()
oanimate()
utilizado en la respuesta aumentará la longitud del código y hará que el código sea inmanejable con el tiempo 🙂 PD: Edité la sugerencia por cierto;)– Bolso Prajyot
5 de septiembre de 2019 a las 3:26
-
Entiendo lo que quieres decir, pero usar jquery requiere que cargues una biblioteca completa, mientras que JS simple no lo hace. No puede simplemente asumir que todos usan jQuery hoy en día. Ser de la vieja escuela no es excusa para escribir respuestas que se aplican solo a una sección de la audiencia en lugar de a un rango más amplio (a menos que la pregunta se etiquete específicamente
jquery
)– Stephan Müller
5 sep 2019 a las 8:40
-
Calmate hermano. No soy bueno en mis habilidades comunicativas >.
– Bolso Prajyot
5 de septiembre de 2019 a las 9:02
Solo algo de información para cualquiera que llegue aquí.
Safari cree que esta es una característica. Hay un informe de error aquí (hágales saber que no le gusta esta “característica” =]).
Cuando abres el teclado, el navegador window
se mueve hacia arriba y su contenido está oculto porque el window
está fuera de la pantalla. También pueden ocurrir otros comportamientos extraños, como el que mostró el OP.
Consulte esta publicación de blog para obtener más detalles y más ejemplos de comportamientos extraños (copié la imagen de arriba): https://blog.opendigerati.com/the-excentric-ways-of-ios-safari-with-the-keyboard-b5aa3f34228d
-
safari es un nuevo IE, eso es lo que dice la gente
– Dzmitri Vasilevski
28 de febrero de 2021 a las 12:18
-
Hay (al menos) 2 errores de Safari aquí: el que vinculaste está relacionado con la retracción del navegador Chrome y 100vh, que se explica mejor aquí: developers.google.com/web/updates/2016/12/url-bar-resizing El segundo error está relacionado con el manejo del teclado en pantalla y el hecho de que Safari agrega altura de desplazamiento cuando el teclado está visible, y este comportamiento no se puede controlar (y no hay un evento de cambio de tamaño u otro evento para detectarlo).
– crimbo
2 de junio de 2021 a las 20:59
puedes probar este css por favor..
html {
height: 100%;
}
body.disable-scroll {
position: fixed;
top:0;
bottom:0;
left:0;
right:0;
height: 100vh;
overflow: hidden;
}
-
No me lo arregló. Safari aún permite el desplazamiento cuando el teclado está abierto. Probado en XS.
– Emilio
3 sep 2019 a las 8:50
-
Hice esto en uno de mis proyectos…
Cuando abras el teclado, usa esto en el cuerpo.
$(body).bind('touchmove', function (e) {
e.preventDefault()
});
Y luego desátalo cuando quieras desplazarte de nuevo.
$(body).unbind('touchmove');
Si lo combinas con height:100% o 100vh y overflow:hidden. Deberia de funcionar.
Es posible escuchar estos cambios de altura de la ventana gráfica en JS:
window.visualViewport.addEventListener(
'resize',
event => console.log(event.target)
);
Esto funciona en iPhone (probado en iPhone 11 físico con iOS 15.1)
documento de MDN: https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API
Mohamad Hamouday
Puede resolverlo ejecutando este script que detecta cuándo se muestra el teclado y agregará la clase “kb_active” al cuerpo y el nuevo valor de desplazamiento como un atributo al cuerpo “data-window-offset” para que podamos usar estos valores en css y otro código javascript
function watch_mobile_keyboard_status(){
// If mobile or tablet
if(window.innerWidth < 950) {
var kb_status = false;
var initial_screen_size = window.innerHeight; // Checks initial height of the screen
var interval_id = window.setInterval(toggle_kb_status, 1000);
function toggle_kb_status(){
if(initial_screen_size > window.innerHeight){
if(!kb_status){
var diff = initial_screen_size - window.innerHeight;
document.querySelector('body').classList.add('kb_active');
document.querySelector('body').setAttribute('data-window-offset', diff);
kb_status = true;
document.dispatchEvent(new Event("change_keyboard_status"));
}
} else {
if(kb_status){
document.querySelector('body').classList.remove('kb_active');
document.querySelector('body').removeAttribute('data-window-offset');
document.dispatchEvent(new Event("change_keyboard_status"));
kb_status = false;
}
}
}
}
}
Y aquí podemos detectar el evento y mover el elemento a la nueva posición
if(is_ios()){
document.addEventListener("change_keyboard_status", function(){
var element = ".nav_box";
var offset = document.querySelector('body').getAttribute('data-window-offset');
if(offset & offset > 50){
if(document.querySelector(element)){
document.querySelector(element).style.top = offset + "px";
}
} else {
document.querySelector(element).style.top = "";
}
});
}
function is_ios() {
return ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(navigator.platform)
|| (navigator.userAgent.includes("Mac") && "ontouchend" in document)
}
Elgun Ezmemmedov
¡¡¡¡¡Resuelto!!!!! Solo agregue esos códigos a su script
//reach out to that input field (When ever u r gonna click tofocus)
let inputField = document.getElementById("input_focused")
/*
* Method 1: Briefly change the opacity.
* Element might "blink" on focus in some scenarios.
*/
inputField.addEventListener("focus", () => {
methodOne.style.opacity = 0;
setTimeout(() => methodOne.style.opacity = 1);
});
<section id="modal">
<input id="input_focused">
</section>
+1 Pasé más de una semana tratando de encontrar a alguien más con este problema. No importa lo que intenté, no pude deshacerme de ese feo espacio blanco en la parte inferior. Dos soluciones posibles son configurar el fondo de la página para que coincida con el fondo del contenido (de modo que el espacio se mezcle con la página y sea menos perceptible). Otra es aplicar
touch-action: none
sobre el<html>
y<body>
elementos cuando los cuadros de texto se enfocan y eliminan el estilo cuando los cuadros de texto pierden el foco (esto necesita Javascript).– Eric Mutta
22 de junio de 2022 a las 20:31