Могу ли я на лету изменить метатег области просмотра в мобильном сафари?

98

У меня есть приложение AJAX, созданное для мобильного браузера Safari, которому необходимо отображать различные типы контента.

Для одного контента мне нужно, user-scalable=1а для другого мне нужно user-scalable=0.

Есть ли способ изменить значение атрибута содержимого без обновления страницы?

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
Перец
источник

Ответы:

148

Я понимаю, что это немного старовато, но да, это можно сделать. Немного javascript для начала:

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

Просто замените нужные части, и Mobile Safari будет учитывать новые настройки.

Обновить:

Если у вас еще нет метатега области просмотра в исходном коде, вы можете добавить его напрямую примерно так:

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

Или, если вы используете jQuery:

$('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">');
Markquezada
источник
2
Ницца! К сожалению, я не могу заставить его работать. Моя ситуация немного иная: я работаю с сайтом шириной 980 пикселей. Контент идет прямо к краю дизайна, поэтому на iPad это выглядит неудобно. Я думал, что установлю окно просмотра на ширину 1020 пикселей, чтобы учесть поле 20 пикселей с каждой стороны ... но не повезло: viewport = document.querySelector("meta[name=viewport]"); viewport.setAttribute('content', 'width=1020'); (Просто для некоторого контекста: я помещаю это в несколько заблокированный экземпляр Drupal ... поэтому у меня нет прямого доступа к области головы, и мне нужно использовать Javascript)
Сэм
7
Это должно быть достаточно просто. Просто впишите это напрямую. Если вы используете jQuery, это будет примерно так: $('head').append('<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">'); или, без jQuery:document.getElementsByTagName('head')[0].appendChild( ... );
markquezada
3
Для атрибутов содержимого веб-инспектор мобильного сафари выдает ошибку при установке точки с запятой. Это кажется более верным:viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0');
jfroom
1
@the_nuts Вы правы, appendChild ожидает узел, а не строку. Обновлено. Спасибо.
markquezada
1
@basZero: вы можете использовать пользовательский агент, чтобы проверить, на каком устройстве запущен скрипт, прежде чем запускать приведенный выше код, но в целом я думаю, что это плохая идея. Постарайтесь сделать обобщения на основе характеристик устройства (или размера экрана, если необходимо), а не реальных устройств. Например, вы можете определить, поддерживает ли устройство сенсорные события и т. Д. (Например, с помощью modernizr ). Зависит от того, что вы пытаетесь сделать.
markquezada
8

в твоем <head>

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

где-то в вашем javascript

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

... но удачи в настройке для вашего устройства, возня в течение нескольких часов ... а меня все еще нет!

источник

Sonjz
источник
4

На этот вопрос по большей части дан ответ, но я расширю ...

Шаг 1

Моя цель состояла в том, чтобы включить масштабирование в одно время и отключить его в другое время.

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

Шаг 2

Тег области просмотра обновился, но масштабирование щипком все еще было активным !! Мне нужно было найти способ, чтобы страница приняла изменения ...

Это хакерское решение, но переключение непрозрачности тела помогло. Я уверен, что есть другие способы добиться этого, но вот что сработало для меня.

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

Шаг 3

Моя проблема в основном была решена на этом этапе, но не совсем. Мне нужно было знать текущий уровень масштабирования страницы, чтобы я мог изменить размер некоторых элементов, чтобы они поместились на странице (подумайте о маркерах карты).

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

Надеюсь, это кому-нибудь поможет. Я несколько часов стучал мышкой, прежде чем нашел решение.

posit labs
источник
Это спасло мне жизнь, но у меня возникла небольшая проблема: если вы отображаете изображение в оверлейном div на 100% и увеличиваете его на мобильном устройстве, вы будете увеличивать масштаб, используя встроенную реализацию масштабирования браузера, которая обычно просто масштабирует видимое. область без повторного рендеринга исходного файла. С другой стороны, если я удалю «width = device-width» для отключенного состояния масштабирования, изображение будет отображаться нормально при масштабировании, но я потеряю позицию на последней странице, когда 100% div закрыт ...
Стефан Мюллер