ios - tamaño - como acomodar el teclado del ipad
¿Cómo impido que mi navegación fija se mueva así cuando se abre el teclado virtual en Mobile Safari? (11)
Agregue javascript de esta manera:
$(function() {
var $body;
if (''ontouchstart'' in window) {
$body = $("body");
document.addEventListener(''focusin'', function() {
return $body.addClass("fixfixed");
});
return document.addEventListener(''focusout'', function() {
$body.removeClass("fixfixed");
return setTimeout(function() {
return $(window).scrollLeft(0);
}, 20);
});
}
});
y agrega una clase como esta:
.fixfixed header{
position: absolute;
}
Puede consultar este artículo: http://dansajin.com/2012/12/07/fix-position-fixed/
Entiendo que el safari móvil tiene muchos errores en elementos fijos, pero en general he logrado que mi diseño funcione correctamente hasta que agregué una entrada de texto muy necesaria para la navegación fija en la parte inferior. Ahora, cuando el usuario se enfoca en el elemento de entrada de texto y aparece el teclado virtual, mi navegación, que siempre se arregla en la parte inferior de la página, salta a un lugar realmente extraño en el medio de la página.
Agregaría parte de mi código a esta publicación, pero no estoy seguro de por dónde empezar. Esa navegación se fija en la parte inferior y se coloca a la izquierda y al fondo 0 y al 100% de ancho. A partir de ahí, no sé lo que está pasando, solo puedo suponer que es un error de safari móvil.
También parece perder su posición fija y volverse relativa, solo mientras el elemento de entrada de texto esté enfocado y el teclado virtual esté abierto.
Las soluciones en la parte superior son algunas maneras de solucionar el problema, pero creo que agregar clases extra de CSS o usar Moderniz nos complican las cosas.
Si quieres una solución más simple, aquí hay una solución no-modernizr no extra-css pero pura jquery y funciona en todos los dispositivos y navegadores que utilizo esta corrección en todos mis proyectos
if (''ontouchstart'' in window) {
$(document).on(''focus'', ''textarea,input,select'', function() {
$(''.navbar.navbar-fixed-top'').css(''position'', ''absolute'');
}).on(''blur'', ''textarea,input,select'', function() {
$(''.navbar.navbar-fixed-top'').css(''position'', '''');
});
}
Los eventos de focusin
y de focusout
parecen estar más adaptados a este problema que los eventos de focus
y blur
, ya que los primeros alcanzan el elemento raíz. Ver esta respuesta en SO.
Personalmente uso AngularJS, así que lo implementé así:
$window.document.body.addEventListener(''focusin'', function(event) {
var element = event.target;
var tagName = element.tagName.toLowerCase();
if(!$rootScope.inputOverlay && (tagName === ''input'' || tagName === ''textarea'' || tagName === ''select'')) {
$rootScope.$apply(function() {
$rootScope.inputOverlay = true;
});
}
});
$window.document.body.addEventListener(''focusout'', function() {
if($rootScope.inputOverlay) {
$rootScope.$apply(function() {
$rootScope.inputOverlay = false;
});
}
});
Nota: Estoy ejecutando este script de manera condicional si este es Safari móvil.
Puse un atributo ng-class
en mi barra de navegación:
<div class="navbar navbar-default navbar-fixed-top" ng-class="{''navbar-absolute'': inputOverlay}">
usando el siguiente CSS:
.navbar-absolute {
position: absolute !important;
}
Ninguna de estas soluciones me funcionó porque mi DOM es complicado y tengo páginas dinámicas de desplazamiento infinito, así que tuve que crear las mías.
Fondo: estoy usando un encabezado fijo y un elemento más abajo que se pega debajo de él una vez que el usuario se desplaza hacia abajo. Este elemento tiene un campo de entrada de búsqueda. Además, tengo páginas dinámicas agregadas durante el desplazamiento hacia adelante y hacia atrás.
Problema: en iOS, cada vez que el usuario hacía clic en la entrada del elemento fijo, el navegador se desplazaba hasta la parte superior de la página. Esto no solo provocó un comportamiento no deseado, sino que también activó mi página dinámica agregada en la parte superior de la página.
Solución esperada: no hay desplazamiento en iOS (ninguno en absoluto) cuando el usuario hace clic en la entrada en el elemento adhesivo.
Solución:
/*Returns a function, that, as long as it continues to be invoked, will not
be triggered. The function will be called after it stops being called for
N milliseconds. If `immediate` is passed, trigger the function on the
leading edge, instead of the trailing.*/
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function is_iOS() {
var iDevices = [
''iPad Simulator'',
''iPhone Simulator'',
''iPod Simulator'',
''iPad'',
''iPhone'',
''iPod''
];
while (iDevices.length) {
if (navigator.platform === iDevices.pop()) { return true; }
}
return false;
}
$(document).on("scrollstop", debounce(function () {
//console.log("Stopped scrolling!");
if (is_iOS()) {
var yScrollPos = $(document).scrollTop();
if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
$(''#searchBarDiv'').css(''position'', ''absolute'');
$(''#searchBarDiv'').css(''top'', yScrollPos + 50 + ''px''); //50 for fixed header
}
else {
$(''#searchBarDiv'').css(''position'', ''inherit'');
}
}
},250,true));
$(document).on("scrollstart", debounce(function () {
//console.log("Started scrolling!");
if (is_iOS()) {
var yScrollPos = $(document).scrollTop();
if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
$(''#searchBarDiv'').css(''position'', ''fixed'');
$(''#searchBarDiv'').css(''width'', ''100%'');
$(''#searchBarDiv'').css(''top'', ''50px''); //50 for fixed header
}
}
},250,true));
Requisitos: Se requiere JQuery Mobile para que funcionen las funciones de inicio y parada.
El rebote se incluye para suavizar cualquier retraso creado por el elemento adhesivo.
Probado en iOS10.
No estaba teniendo suerte con la solución propuesta por Dan Sajin. Tal vez el error ha cambiado desde que escribió esa publicación de blog, pero en iOS 7.1, el error siempre aparecerá cuando la posición se cambie a fija después de que la entrada esté borrosa, incluso si demora hasta que el teclado del software esté oculto por completo. La solución a la que llegué implica esperar un evento de touchstart
lugar del evento de blur
, ya que el elemento fijo siempre vuelve a su posición correcta cuando se desplaza la página.
if (Modernizr.touch) {
var $el, focused;
$el = $(''body'');
focused = false;
$(document).on(''focus'', ''input, textarea, select'', function() {
focused = true;
$el.addClass(''u-fixedFix'');
}).on(''touchstart'', ''input, textarea, select'', function() {
// always execute this function after the `focus` handler:
setTimeout(function() {
if (focused) {
return $el.removeClass(''u-fixedFix'');
}
}, 1);
});
}
HTH
Prueba esta. Funciona. Solo lo pruebo.
$(document).on(''focus'',''input'', function() {
setTimeout(function() {
$(''#footer1'').css(''position'', ''absolute'');
$(''#header1'').css(''position'', ''absolute'');
}, 0);
});
$(document).on(''blur'',''input'', function() {
setTimeout(function() {
$(''#footer1'').css(''position'', ''fixed'');
$(''#header1'').css(''position'', ''fixed'');
}, 800);
});
Realmente me gusta la solución anterior. Lo empaqué en un pequeño plugin jQuery para poder:
- Establecer qué padre obtiene la clase
- Establezca los elementos a los que esto se aplica (no olvide "textarea" y "select").
- Establecer cuál es el nombre de la clase principal
- Permitir que sea encadenado
- Permitir que se use varias veces
Ejemplo de código:
$.fn.mobileFix = function (options) {
var $parent = $(this),
$fixedElements = $(options.fixedElements);
$(document)
.on(''focus'', options.inputElements, function(e) {
$parent.addClass(options.addClass);
})
.on(''blur'', options.inputElements, function(e) {
$parent.removeClass(options.addClass);
// Fix for some scenarios where you need to start scrolling
setTimeout(function() {
$(document).scrollTop($(document).scrollTop())
}, 1);
});
return this; // Allowing chaining
};
// Only on touch devices
if (Modernizr.touch) {
$("body").mobileFix({ // Pass parent to apply to
inputElements: "input,textarea,select", // Pass activation child elements
addClass: "fixfixed" // Pass class name
});
}
Tomando de lo que hizo sylowgreen, la clave es arreglar el body
al ingresar la input
. Así:
$("#myInput").on("focus", function () {
$("body").css("position", "fixed");
});
$("#myInput").on("blur", function () {
$("body").css("position", "static");
});
Tuve un problema similar, pero encontré una solución agregando la siguiente clase css al elemento body en el foco de entrada y luego quitándolo nuevamente en unfocus:
.u-oh {
overflow: hidden;
height: 100%;
width: 100%;
position: fixed;
}
Yo uso este script jQuery:
var focus = 0;
var yourInput = $(".yourInputClass");
yourInput.focusin(function(){
if(!focus) {
yourInput.blur();
$("html, body").scrollTop($(document).height());
focus = 1;
}
if(focus) {
yourInput.focus();
focus = 0;
}
});
Funciona perfectamente para mi
http://dansajin.com/2012/12/07/fix-position-fixed/ esta es una de las soluciones propuestas. Parece que vale la pena intentarlo.
En resumen: establezca fixed
elementos fixed
en la position:absolute
cuando se focus
cualquier entrada y reinícielos cuando ese elemento esté blur
rojo
.header {
position: fixed;
}
.footer {
position: fixed;
}
.fixfixed .header,
.fixfixed .footer {
position: absolute;
}
y
if (''ontouchstart'' in window) {
/* cache dom references */
var $body = $(''body'');
/* bind events */
$(document)
.on(''focus'', ''input'', function() {
$body.addClass(''fixfixed'');
})
.on(''blur'', ''input'', function() {
$body.removeClass(''fixfixed'');
});
}