¿Puedo cambiar la metaetiqueta de la ventana gráfica en safari móvil sobre la marcha?

98

Tengo una aplicación AJAX creada para el navegador Safari móvil que necesita mostrar diferentes tipos de contenido.

Para algunos contenidos, necesito user-scalable=1y para otros, necesito user-scalable=0.

¿Hay alguna forma de modificar el valor del atributo de contenido sin actualizar la página?

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
Pimienta
fuente

Respuestas:

148

Me doy cuenta de que esto es un poco viejo, pero sí se puede hacer. Algunos javascript para comenzar:

viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0');

Simplemente cambie las partes que necesita y Mobile Safari respetará la nueva configuración.

Actualizar:

Si aún no tiene la etiqueta meta de la ventana gráfica en la fuente, puede agregarla directamente con algo como esto:

var metaTag=document.createElement('meta');
metaTag.name = "viewport"
metaTag.content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
document.getElementsByTagName('head')[0].appendChild(metaTag);

O si está usando jQuery:

$('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">');
markquezada
fuente
2
¡Agradable! Desafortunadamente, parece que no puedo hacer que funcione. Mi situación es un poco diferente: estoy trabajando con un sitio que tiene un ancho de 980px. El contenido va directo al borde del diseño, por lo que en un iPad parece extraño. Pensé que establecería la ventana gráfica en un ancho de 1020px para permitir un margen de 20px a cada lado ... pero no viewport = document.querySelector("meta[name=viewport]"); viewport.setAttribute('content', 'width=1020'); tuve suerte: (Solo para un poco de contexto: estoy poniendo esto en una instancia de Drupal algo bloqueada ... así que no tengo acceso directo al área de la cabeza y necesito usar Javascript)
Sam
7
Esto debería ser bastante fácil. Simplemente escríbalo directamente. Si está usando jQuery sería algo como esto: $('head').append('<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">'); o, sin jQuery:document.getElementsByTagName('head')[0].appendChild( ... );
markquezada
3
Para los atributos de contenido, el inspector web de Mobile Safari arroja un error en el punto y coma. Esto parece ser más válido:viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0');
jfroom
1
@the_nuts Tienes razón, appendChild espera un nodo, no una cadena. Actualizado. Gracias.
markquezada
1
@basZero: podría usar el agente de usuario para verificar en qué dispositivo se está ejecutando el script antes de ejecutar el código anterior, pero en general creo que es una mala idea. Trate de generalizar según las características del dispositivo (o el tamaño de la pantalla si es necesario), no los dispositivos reales. Por ejemplo, puede detectar si el dispositivo admite eventos táctiles, etc. (es decir, con modernizr ). Depende de lo que intentes hacer.
markquezada
8

en tus <head>

<meta id="viewport"
      name="viewport"
      content="width=1024, height=768, initial-scale=0, minimum-scale=0.25" />

en algún lugar de tu javascript

document.getElementById("viewport").setAttribute("content",
      "initial-scale=0.5; maximum-scale=1.0; user-scalable=0;");

... pero buena suerte con ajustarlo para tu dispositivo, jugando durante horas ... ¡y todavía no estoy allí!

fuente

sonjz
fuente
4

Esto ha sido respondido en su mayor parte, pero ampliaré ...

Paso 1

Mi objetivo era habilitar el zoom en ciertos momentos y deshabilitarlo en otros.

// enable pinch zoom
var $viewport = $('head meta[name="viewport"]');    
$viewport.attr('content', 'width=device-width, initial-scale=1, maximum-scale=4');

// ...later...

// disable pinch zoom
$viewport.attr('content', 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no');

Paso 2

La etiqueta de la ventana gráfica se actualizaría, ¡pero el zoom aún estaba activo! Tenía que encontrar una manera de que la página recogiera los cambios ...

Es una solución de pirateo, pero alternar la opacidad del cuerpo funcionó. Estoy seguro de que hay otras formas de lograr esto, pero esto es lo que funcionó para mí.

// after updating viewport tag, force the page to pick up changes           
document.body.style.opacity = .9999;
setTimeout(function(){
    document.body.style.opacity = 1;
}, 1);

Paso 3

Mi problema se resolvió en su mayoría en este punto, pero no del todo. Necesitaba saber el nivel de zoom actual de la página para poder cambiar el tamaño de algunos elementos para que quepan en la página (piense en los marcadores del mapa).

// check zoom level during user interaction, or on animation frame
var currentZoom = $document.width() / window.innerWidth;

Espero que esto ayude a alguien. Pasé varias horas golpeando el mouse antes de encontrar una solución.

laboratorios de postulación
fuente
Esto me salvó la vida, pero tengo un pequeño problema: suponiendo que muestre una imagen en un div superpuesto al 100% y amplíela en un dispositivo móvil, hará zoom utilizando la implementación de zoom nativa del navegador que generalmente simplemente escala el visible área sin tener que volver a renderizar el archivo original. Por otro lado, si elimino "width = device-width" para el estado de zoom desactivado, la imagen se ve bien al hacer zoom, pero pierdo la posición de mi última página cuando el div del 100% está cerrado ...
Stefan Müller