Czy mogę zmienić metatag viewport w mobilnym safari w locie?

98

Mam aplikację AJAX stworzoną dla mobilnej przeglądarki Safari, która musi wyświetlać różne rodzaje treści.

Do niektórych treści potrzebuję, user-scalable=1a do innych potrzebuję user-scalable=0.

Czy istnieje sposób na zmodyfikowanie wartości atrybutu content bez odświeżania strony?

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
Pieprz
źródło

Odpowiedzi:

148

Zdaję sobie sprawę, że to trochę stare, ale tak, można to zrobić. Trochę javascript na początek:

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

Po prostu zmień potrzebne części, a Mobile Safari zastosuje nowe ustawienia.

Aktualizacja:

Jeśli nie masz jeszcze metatagu viewport w źródle, możesz dodać go bezpośrednio za pomocą czegoś takiego:

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

Lub jeśli używasz jQuery:

$('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">');
markquezada
źródło
2
Miły! Niestety nie wydaje mi się, żeby to działało. Moja sytuacja jest nieco inna: pracuję z witryną o szerokości 980 pikseli. Treść dociera do krawędzi projektu, więc na iPadzie wygląda niezręcznie. Pomyślałem, że ustawię obszar roboczy na szerokość 1020 pikseli, aby umożliwić margines 20 pikseli po obu stronach ... ale bez powodzenia: viewport = document.querySelector("meta[name=viewport]"); viewport.setAttribute('content', 'width=1020'); (tylko w pewnym kontekście: umieszczam to w nieco zablokowanej instancji Drupala ... więc nie mam bezpośredniego dostępu do obszaru głowy i muszę używać Javascript)
Sam
7
To powinno być dość łatwe. Po prostu napisz to bezpośrednio. Jeśli używasz jQuery byłoby coś takiego: $('head').append('<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">'); lub bez jQuery:document.getElementsByTagName('head')[0].appendChild( ... );
markquezada
3
W przypadku atrybutów treści inspektor sieci Web na urządzeniach mobilnych wyświetla błąd w średnikach. Wydaje się, że jest to bardziej aktualne:viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0');
jfroom
1
@the_nuts Masz rację, appendChild oczekuje węzła, a nie ciągu. Zaktualizowano. Dzięki.
markquezada
1
@basZero: Możesz użyć agenta użytkownika, aby sprawdzić, na którym urządzeniu działa skrypt, przed uruchomieniem powyższego kodu, ale ogólnie uważam, że to zły pomysł. Spróbuj uogólnić na podstawie funkcji urządzenia (lub rozmiaru ekranu, jeśli musisz), a nie rzeczywistych urządzeń. Na przykład możesz wykryć, czy urządzenie obsługuje zdarzenia dotykowe itp. (Tj. Za pomocą modernizr ). Zależy od tego, co próbujesz zrobić.
markquezada,
8

w Twoim <head>

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

gdzieś w twoim javascript

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

... ale powodzenia w dostosowywaniu go do swojego urządzenia, majstrowaniu godzinami ... i nadal mnie tam nie ma!

źródło

sonjz
źródło
4

W większości odpowiedzi na to pytanie, ale rozszerzę ...

Krok 1

Moim celem było włączenie zoomu w określonych momentach i wyłączenie go w innych.

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

Krok 2

Znacznik rzutni aktualizował się, ale powiększanie przez szczypanie było nadal aktywne! Musiałem znaleźć sposób, aby strona odebrała zmiany ...

To hackowe rozwiązanie, ale przełączenie krycia ciała załatwiło sprawę. Jestem pewien, że istnieją inne sposoby, aby to osiągnąć, ale oto, co zadziałało dla mnie.

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

Krok 3

Mój problem został w większości rozwiązany w tym momencie, ale nie do końca. Musiałem znać aktualny poziom powiększenia strony, aby móc zmienić rozmiar niektórych elementów, aby zmieściły się na stronie (pomyśl o znacznikach mapy).

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

Mam nadzieję, że to komuś pomoże. Spędziłem kilka godzin uderzając myszą, zanim znalazłem rozwiązanie.

posit labs
źródło
To uratowało mi życie, ale mam z tym mały problem: zakładając, że wyświetlasz obraz w nakładce div w 100% i powiększasz go na urządzeniu mobilnym, będziesz powiększać za pomocą natywnej implementacji powiększenia przeglądarki, która zwykle po prostu skaluje widoczne obszar bez ponownego renderowania oryginalnego pliku. Z drugiej strony, jeśli usunę "width = device-width" dla wyłączonego stanu powiększenia, renderuje obraz dobrze podczas powiększania, ale tracę moją ostatnią pozycję na stronie, gdy 100% div jest zamknięty ...
Stefan Müller