Puis-je modifier à la volée la balise Meta de la fenêtre d'affichage dans Mobile Safari?

98

J'ai une application AJAX conçue pour le navigateur Safari mobile qui doit afficher différents types de contenu.

Pour certains contenus, j'ai besoin user-scalable=1et pour d'autres, j'ai besoin user-scalable=0.

Existe-t-il un moyen de modifier la valeur de l'attribut de contenu sans actualiser la page?

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

Réponses:

148

Je me rends compte que c'est un peu vieux, mais, oui, cela peut être fait. Quelques javascript pour vous aider à démarrer:

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

Changez simplement les pièces dont vous avez besoin et Mobile Safari respectera les nouveaux paramètres.

Mettre à jour:

Si vous n'avez pas déjà la balise meta viewport dans la source, vous pouvez l'ajouter directement avec quelque chose comme ceci:

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);

Ou si vous utilisez jQuery:

$('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">');
markquezada
la source
2
Agréable! Malheureusement, je n'arrive pas à le faire fonctionner. Ma situation est un peu différente: je travaille avec un site d'une largeur de 980px. Le contenu va jusqu'au bord de la conception, donc sur un iPad, cela semble gênant. Je pensais que j'avais défini la fenêtre sur une largeur de 1020px pour permettre une marge de 20px de chaque côté ... mais pas de chance: viewport = document.querySelector("meta[name=viewport]"); viewport.setAttribute('content', 'width=1020'); (Juste pour un certain contexte: je mets cela dans une instance Drupal quelque peu verrouillée ... donc je n'ai pas d'accès direct à la zone de la tête et dois utiliser Javascript)
Sam
7
Cela devrait être assez simple. Écrivez-le directement. Si vous utilisez jQuery, ce serait quelque chose comme ceci: $('head').append('<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">'); ou, sans jQuery:document.getElementsByTagName('head')[0].appendChild( ... );
markquezada
3
Pour les attributs de contenu, l'inspecteur Web de mobile safari lance une erreur sur les points-virgules. Cela semble être plus valide:viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0');
jfroom
1
@the_nuts Vous avez raison, appendChild attend un nœud, pas une chaîne. Actualisé. Merci.
markquezada
1
@basZero: Vous pouvez utiliser l'agent utilisateur pour vérifier sur quel périphérique le script s'exécute avant d'exécuter le code ci-dessus, mais en général, je pense que c'est une mauvaise idée. Essayez de généraliser en fonction des fonctionnalités de l'appareil (ou de la taille de l'écran si nécessaire), et non des appareils réels. Par exemple, vous pouvez détecter si l'appareil prend en charge les événements tactiles, etc. (c'est-à-dire avec modernizr ). Cela dépend de ce que vous essayez de faire.
markquezada
8

dans votre <head>

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

quelque part dans votre javascript

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

... mais bonne chance pour le peaufiner pour votre appareil, jouer pendant des heures ... et je ne suis toujours pas là!

la source

sonjz
la source
4

Cela a été répondu pour la plupart, mais je vais développer ...

Étape 1

Mon objectif était d'activer le zoom à certains moments et de le désactiver à d'autres.

// 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');

Étape 2

La balise de la fenêtre serait mise à jour, mais le zoom par pincement était toujours actif !! J'ai dû trouver un moyen pour que la page reprenne les modifications ...

C'est une solution de piratage, mais basculer l'opacité du corps a fait l'affaire. Je suis sûr qu'il existe d'autres façons d'accomplir cela, mais voici ce qui a fonctionné pour moi.

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

Étape 3

Mon problème a été en grande partie résolu à ce stade, mais pas tout à fait. J'avais besoin de connaître le niveau de zoom actuel de la page afin de pouvoir redimensionner certains éléments pour les adapter à la page (pensez aux marqueurs de carte).

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

J'espère que cela aide quelqu'un. J'ai passé plusieurs heures à frapper ma souris avant de trouver une solution.

posit labs
la source
Cela m'a sauvé la vie, mais j'ai un petit problème avec cela: en supposant que vous affichez une image dans une superposition div à 100% et que vous zoomez dessus sur un appareil mobile, vous zoomerez en utilisant l'implémentation de zoom du navigateur natif qui met généralement à l'échelle le visible zone sans aucun rendu du fichier d'origine. De l'autre côté, si je supprime "width = device-width" pour l'état de zoom désactivé, cela rend l'image correcte pendant le zoom mais je perds ma dernière position de page lorsque le div 100% est fermé ...
Stefan Müller