відключити режим перегляду масштабування if 10+ safari?


164

Я обновляю свій iPhone 6 плюс до прошивці 10 бета - версію і тільки виявив , що в мобільному сафарі, ви можете збільшити будь-який веб - сторінку з допомогою подвійного постукування або защемлень ігнорують в user-scalable=noкод в мета - тезі. Я не знаю, це помилка чи функція. Якщо це розглядається як особливість, як відключити масштаб прогляду в огляді iOS 10?


оновлено у версії iOS 11/12, iOS 11 та safari iOS 12 досі НЕ поважають user-scalable=noметатег.

мобільний сайт github на Safari


2
Особливість доступності:
Помітно

87
Ні, це не так. Це нормальна норма для нормального веб-контенту. Для веб-додатків поведінка масштабування за замовчуванням може повністю зруйнувати зручність використання. Наприклад, ніхто не хоче збільшувати кнопку збільшення каналу, оскільки вони натискали її двічі, а також не збільшували частину відеоігри, оскільки двічі натискали кнопку стрибка. Існує причина, що ця функція була додана в першу чергу, і немає сенсу порушувати зручність використання для всіх лише тому, що кілька "веб-дизайнерів" не знають, що вони роблять. Ідіть криком на дизайнерів сайту і киньте ламати браузер.
dgatwood

36
Скажімо, що це "погана практика" - це думка, і це не змінює факту того, що Apple наполегливо дотримується веб-стандартів, які спільнота проводить місяцями / роками / десятиліттями, впроваджуючи крос-платформу та виконуючи велике лайно. Чому Apple повинна диктувати, що веб-дизайнери не знають, що вони роблять? Страшний аргумент.
samrap

2
Особисто я думаю, що це випливає з кодового коду в Інтернеті, де розробники просто копіюють та вклеюють наосліп, не знаючи, яка мета коду.
Вільям Істед

7
Apple відповідь проста: Apple: зробіть відключення метатега налаштуванням доступності за замовчуванням. Ті, хто цього потребує, матимуть це, не караючи тих, хто цього не потребує.
Рубен Мартинес-молодший

Відповіді:


94

Можна запобігти масштабуванню веб-сторінок у сафарі на iOS 10, але це потребує більшої роботи з вашого боку. Я здогадуюсь, аргумент полягає в тому, що ступінь складності повинна зупинити вантажні культові диски, щоб вони не потрапляли на "користувач, що масштабується = ні", у кожен тег огляду та робили речі непотрібними для користувачів із порушеннями зору.

Все ж хотілося б, щоб Apple змінила свою реалізацію, щоб існував простий (мета-тег) спосіб відключити подвійне торкання до збільшення. Більшість труднощів пов'язані з цією взаємодією.

Ви можете зупинити прискорене збільшення масштабу таким чином:

document.addEventListener('touchmove', function (event) {
  if (event.scale !== 1) { event.preventDefault(); }
}, false);

Зауважте, що якщо якісь більш глибокі цілі викликають stopPropagation події, подія не дійде до документа, і поведінка масштабування не завадить цьому слухачеві.

Вимкнення подвійного натискання масштабу подібне. Ви вимкнете будь-який дотик до документа, що відбувається протягом 300 мілісекунд від попереднього натискання:

var lastTouchEnd = 0;
document.addEventListener('touchend', function (event) {
  var now = (new Date()).getTime();
  if (now - lastTouchEnd <= 300) {
    event.preventDefault();
  }
  lastTouchEnd = now;
}, false);

Якщо ви неправильно налаштуєте елементи форми, фокусування на вводі автоматично збільшить масштаб, а оскільки ви в основному відключили ручне збільшення, знімати масштаб тепер буде майже неможливо. Переконайтеся, що розмір вхідного шрифту> = 16 пікс.

Якщо ви намагаєтеся вирішити це в WKWebView в нативній програмі, рішення, наведене вище, є життєздатним, але це краще рішення: https://stackoverflow.com/a/31943976/661418 . І як уже згадувалося в інших відповідях, в iOS 10 beta 6 Apple тепер подала прапор на честь метатега.

Оновлення травня 2017 року: я замінив старий метод "check touch touch on touchstart", щоб відключити "pinch-zoom" більш простим підходом "check event.scale on touchmove". Має бути більш надійним для всіх.


3
Зауважте, що хакерство touchstart непослідовно ... і якщо вам вдасться пройти його стороною, ви застрягли в дуже незручному стані
Сем Сафрон

5
Напр. Повноекранні програми для картографування, у програмі картографування є функція масштабування, яка жорстко кодується (Google Maps JS, Leaflet тощо). Google радить додавати метатег, <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />і якщо браузер не поважає метатег, це дуже поганий дизайн браузера. Інший такий, як дуже поганий дизайн, - це назад / вперед дії за допомогою ковзання, чого неможливо запобігти в iOS 9/10. Це сильно затягує дії всередині веб-програми.
Тімо Кехьонен

4
Якщо користувач почне перетягувати одним пальцем, то поклавши другий палець на екран, він зможе притиснути масштаб. Ви можете відключити і масштабування і прокручування з preventDefaultON touchmove. Не можна (повністю) відключити масштабування, не вимкнувши прокрутку.
Паоло

10
Ого, ця частина (я вставлю тут) була СУПЕР корисною для мене. Я ще не бачив цього згаданого ще в Інтернеті. Щоб вирішити цю проблему, мені знадобилися години. Я дуже розчарований у виборі дизайну Apple UX щодо цього, коли формує автоматичне збільшення, але потім не збільшує масштаб. If you don't set up your form elements right, focusing on an input will auto-zoom, and since you have mostly disabled manual zoom, it will now be almost impossible to unzoom. Make sure the input font size is >= 16px.
Райан

6
Схоже, це вже не працює в iOS 12. Будь-яка ідея, як зробити цю роботу для iOS 12?
TJR

78

Це нова функція в iOS 10.

З приміток до випуску бета-версії iOS 10:

  • Щоб покращити доступність веб-сайтів у Safari, користувачі тепер можуть здійснювати масштабне збільшення, навіть коли веб-сайт встановлюється user-scalable=noу вікні перегляду.

Я очікую, що ми скоро побачимо надбудову JS, щоб дещо відключити це.


4
@Onza: Я не думаю, що це погано. Я думаю, що це добре. Вимкнення защемлення / збільшення (поводження користувача за замовчуванням) вважається поганим, і багато мобільних веб-сайтів роблять це. Єдиним прийнятним випадком для користувачів буде справжній веб-додаток, який виглядає і виглядає як додаток.
wouterds

6
Погано .. Я змінюю вікно перегляду за допомогою js та блокую зум лише тоді, коли на веб-сайті вибираються деякі елементи, тепер він порушений через це "рішення". Якщо хтось вирішить його заблокувати - є причина.
Женя

9
@Karlth це дуже зручне місце для розробника гри
Sandeep

14
У мене IOS 10.0.2, масштабований користувачем = ні, більше не вимикає масштабування на нашому веб-сайті ... Наша основна проблема із збільшенням - це наше фіксоване бічне меню. Це просто порушує макет .. Будь-які ідеї чи рішення щодо цього? Я розумію, що масштабування корисне для доступності, ми зробили масштабування доступним на певних частинах нашого веб-сайту за допомогою js подій (молот) та css .. Я не бачу, чому потрібно вводити правило для всіх, схоже, запускається ПК поліції перейняти і наш світ розробок ?!
webkit

50
"Єдиним прийнятним випадком для користувачів буде справжній веб-додаток, який виглядає і відчуває себе як додаток." - і це, як ви сказали, реальний, прийнятний варіант використання, тобто не що рідкість ..
Флорі

21

Мені вдалося виправити це за допомогою touch-actionвластивості css на окремих елементах. Спробуйте встановити touch-action: manipulation;елементи, на які зазвичай натискають, наприклад, посилання або кнопки.


1
"маніпуляція" не запобігає прискореному масштабуванню, лише збільшення подвійного дотику.
Moos

4
Це має бути прийнятою відповіддю. ви можете використовувати touch-action: none;для керування всіма жестами самостійно.
Гай Софер

4
це чудово - вимкнення масштабування подвійним натисканням, залишаючи масштабування, що МОЖЕ вважатись жестом - подвійне натискання не повинно. 1 собака - собака. 1 собака + 1 собака не робить космічний човник. Це 2 собаки, і вони роблять те, що ви очікували б зробити 2 собаки. Я ніколи не очікував, що 2 собаки будуть космічним човником. Ніколи.
Ларрі

5
@GuySopher iOS не надає touch-action: noneлише те manipulatoin, що залишає проблему із збільшенням масштабування такою, якою вона є.
humanityANDpeace

14

Здається, що ця поведінка нібито змінилася в останній бета-версії, яка на момент написання - бета-6.

З приміток до випуску для iOS 10 Beta 6:

WKWebViewтепер за замовчуванням поважає user-scalable=noз огляду. Клієнти програми WKWebViewможуть покращити доступність і дозволити користувачам натискати та збільшувати масштаб на всіх сторінках, встановивши WKWebViewConfiguration властивість ignoresViewportScaleLimitsна YES.

Однак під час мого (дуже обмеженого) тестування я поки не можу підтвердити це.

Редагувати: перевірено, user-scalable=noдля мене iOS 10 Beta 6 відповідає умовами за замовчуванням.


11
10.0.1 тут. Не поважає. Що з Apple, позбувшись функцій, які потрібні всім ..
lifwanian

1
Це стосується WKWebView не Сафарі. Джерело: Одне з наших програм на карті зламалось, і ми не маємо уявлення, як це виправити.
Фабіо Полоні

Ага! Вибачте, я прийшов сюди, коли шукав рішення тієї самої помилки / функції WKWebViewта свого роду припускав, що оригінальне запитання, про яке ви задавались, WKWebViewколи писав свою відповідь. Тож я припускаю, що під час однієї з перших бета-версій Apple змінила поведінку як WKWebViewмобільного Safari, так і в бета-6, вони змінили поведінку, WKWebViewале зберегли це для мобільного Safari.
Селлан

1
10.0.2 не поважає user-scalable=no. Я не впевнений, чому вони коли-небудь це скасуватимуть, тільки щоб повернути його назад, тільки щоб знову його зняти.
Айдан Хакіміан

13

Щоб обійти цю проблему , яка працює в Mobile Safari в цей час написання, щоб мати третій аргумент в addEventListenerВЕ { passive: false }, так в повній мірі обійти це виглядає наступним чином :

document.addEventListener('touchmove', function (event) {
  if (event.scale !== 1) { event.preventDefault(); }
}, { passive: false });

Ви можете перевірити, чи підтримуються варіанти, щоб вони залишалися сумісними назад.


3
Хтось спробував це на iOS 12? Я додав вищевказаний код, і він нічого не робить для мого веб-сайту. Ще вдається збільшити масштаб цього дурного Safari. Моя мета - тег вікна перегляду виглядає наступним чином : до речі <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">.
Патрік Давадер

1
@PatrickDaVader Так, не вдається знайти жодне робоче рішення для iOS 12 Safari. Отримати морську хворобу від невпинного масштабування.
Джеймі Береза

1
Цей працює в iOS 13. Мої теги <meta> включають: <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no, shrink-to-fit=no" />і<meta name="HandheldFriendly" content="true">
Стерлінг Борн,

1
@SterlingBourne Скопіював налаштування. Працює, але лише як 90% часу. Не впевнений, чому б не весь час.
Hillcow

1
@SterlingBourne відповідь працював на мене! Дякую. Він повинен розміщувати це як відповідь, а не коментар, щоб його можна було проголосувати <meta name = "viewport" content = "width = пристрою-шириною, початковою шкалою = 1, максимальною шкалою = 1, viewport-fit = cover, user-scalable = no, shrink-to-fit = no "/> та <meta name =" HandheldFriendly "content =" true ">
Джин Блек

8

Я витратив близько години, шукаючи більш надійний варіант JavaScript, і не знайшов його. Так буває, що за останні кілька днів я спіткнувся з hammer.js (Hammer.js - це бібліотека, яка дозволяє вам легко маніпулювати всілякими подіями дотику), і, головним чином, не вдається зробити те, що я намагався зробити.

З цим застереженням, і розуміючи, що я аж ніяк не експерт з JavaScript, це рішення, яке я придумав, в основному використовує hammer.js для зйомки подій "збільшення" та подвійного натискання, а потім увімкнення та відкидання їх.

Переконайтеся, що ви включили hammer.js на свою сторінку, а потім спробуйте вставити цей javascript в голову десь:

< script type = "text/javascript" src="http://hammerjs.github.io/dist/hammer.min.js"> < /script >
< script type = "text/javascript" >

  // SPORK - block pinch-zoom to force use of tooltip zoom
  $(document).ready(function() {

    // the element you want to attach to, probably a wrapper for the page
    var myElement = document.getElementById('yourwrapperelement');
    // create a new hammer object, setting "touchAction" ensures the user can still scroll/pan
    var hammertime = new Hammer(myElement, {
      prevent_default: false,
      touchAction: "pan"
    });

    // pinch is not enabled by default in hammer
    hammertime.get('pinch').set({
      enable: true
    });

    // name the events you want to capture, then call some function if you want and most importantly, add the preventDefault to block the normal pinch action
    hammertime.on('pinch pinchend pinchstart doubletap', function(e) {
      console.log('captured event:', e.type);
      e.preventDefault();
    })
  });
</script>


Я також намагався вирішити цю проблему під час роботи з hammer.js, і можу підтвердити, що я міг запобігти масштабуванню вікна перегляду, додавши .preventDefaultдо всіх обробників жестів молотка. Я спільно використовую пальцем / pinch / pan / tap, я додав його до всіх обробників, я не знаю, чи є конкретний, який виконує цю роботу.
Конан

6

Я спробував попередню відповідь про збільшення зуму

document.documentElement.addEventListener('touchstart', function (event) {
    if (event.touches.length > 1) {
        event.preventDefault();
    }
}, false);

проте колись екран все ще збільшується, коли event.touches.length> 1 Я дізнався, що найкращим способом є подія touchmove, щоб уникнути переміщення пальця по екрану. Код буде приблизно таким:

document.documentElement.addEventListener('touchmove', function (event) {
    event.preventDefault();      
}, false);

Сподіваюся, це допоможе.


7
Це працює лише в тому випадку, якщо ваш додаток ідеально підходить ... якщо у вас є вміст, який можна прокручувати, він не працює ... все-таки приємний злом для деяких сценаріїв.
eljamz

8
Це навіть відключає прокрутку на веб-сайті .. BAD
Gags

@eljamz спасибі за те, що дай мені знати, і так ... мій додаток ідеально підходить на екрані.
Chihying Wu

@Gags Я ще не перевірив функцію прокрутки, дякую, дайте мені знати.
Chihying Wu

6

Перевірте масштабний коефіцієнт у події Touchove, а потім запобігайте дотику.

document.addEventListener('touchmove', function(event) {
    event = event.originalEvent || event;
    if(event.scale > 1) {
        event.preventDefault();
    }
}, false);

2
iOS 13 змінити false на {passive: false}
wayofthefuture

6

Ми можемо отримати все, що хочемо, ввівши одне правило стилю та перехопивши масштабування подій:

$(function () {
  if (!(/iPad|iPhone|iPod/.test(navigator.userAgent))) return
  $(document.head).append(
    '<style>*{cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}</style>'
  )
  $(window).on('gesturestart touchmove', function (evt) {
    if (evt.originalEvent.scale !== 1) {
      evt.originalEvent.preventDefault()
      document.body.style.transform = 'scale(1)'
    }
  })
})

Вимикає прищепне збільшення.

✔ Вимкнення подвійного торкання масштабу.

✔ Прокрутка не впливає.

✔ Вимикає виділення крана (яке спрацьовує на iOS, за допомогою правила стилю).

ПРИМІТКА: Налаштуйте детектор iOS на свій смак. Детальніше про це тут .


Вибачте лукеяксон та Пьотр Ковальський , відповіді яких відображаються в модифікованому вигляді в наведеному вище коді.


Це працює на моєму емуляторі iPad, на якому працює iOS 11.2. На моєму реальному iPad під управлінням iOS 11.3 він не працює. Я додав console.log, щоб переконатися, що події запущені, і щоб вони з'явилися в консолі. Це щось стосується iOS 11.3? Або з реальними пристроями?
Матьє Р.

1
@MathieuR. Це випуск iOS 11.3. Його можна виправити, використовуючи один із addEventListenerзаснованих відповідей і передаючи { passive: false }як optionsпараметр замість false. Однак для зворотної сумісності вам потрібно пройти, falseякщо passiveполе опцій не підтримується. Дивіться developer.mozilla.org/en-US/docs/Web/API/EventTarget/…
Джош Галлахер

@JoshGallagher Чи можете ви надати робочий приклад? На iOS11 жодна з відповідей не працює для мене.
Мік

'Gesturestart' -> prevenDefault працює для мене під час написання на iOS 12,2
Майкл Камден

5

Я придумав досить наївне рішення, але, здається, працює. Моєю метою було запобігти трактуванню випадкових подвійних натискань як збільшення, зберігаючи при цьому щільний пристрій для збільшення доступності.

Ідея полягає у вимірюванні часу між першим touchstartі другим touchendу подвійному торканні, а потім інтерпретації останнього touchendяк клацання, якщо затримка занадто мала. Незважаючи на те, що запобігає випадковому масштабуванню, цей метод, як видається, не зачіпає прокрутку списку, що добре. Не впевнений, якщо я нічого не пропустив.

let preLastTouchStartAt = 0;
let lastTouchStartAt = 0;
const delay = 500;

document.addEventListener('touchstart', () => {
  preLastTouchStartAt = lastTouchStartAt;
  lastTouchStartAt = +new Date();
});
document.addEventListener('touchend', (event) => {
  const touchEndAt = +new Date();
  if (touchEndAt - preLastTouchStartAt < delay) {
    event.preventDefault();
    event.target.click();
  }
});

Натхненний сутью від немитої зими та відповіді Йосифа .


5

У моєму конкретному випадку я використовую Babylon.js для створення тривимірної сцени, і вся моя сторінка складається з одного повного екранного полотна. 3D-двигун має власну функцію масштабування, але в iOS перешкоджає прискорене збільшення. Я оновив відповідь @Joseph, щоб подолати свою проблему. Щоб його відключити, я зрозумів, що мені потрібно передавати {пасивний: помилковий} як варіант слухачеві події. Наступний код працює для мене:

window.addEventListener(
    "touchmove",
    function(event) {
        if (event.scale !== 1) {
            event.preventDefault();
        }
    },
    { passive: false }
);

Мій випадок використання - це також повна сторінка 3d сцени із спеціальними елементами управління. Я був би потоплений, якби не було вирішення Apple, явно ігноруючи масштаб користувача: немає мета.
Нік Білик

1

Як не дивно це звучить, принаймні для Safari в iOS 10.2, подвійне натискання на масштабування магічним чином відключається, якщо ваш елемент або хтось із його предків має одну з наступних дій:

  1. Слухач onClick - це може бути простий нооп.
  2. cursor: pointerНабір в CSS

як щодо прищипування?
Сем Су

На жаль, це рішення не охоплено притискання масштабу. Для цього ми використовували рішення , запропоноване в: stackoverflow.com/a/39594334/374196
mariomc

Не працює для мене. Я використовую 10.2.1 Beta 4 на iPod Touch за допомогою цієї тестової сторінки та двічі торкніться будь-якого із сивих квадратів масштабування: jsbin.com/kamuta/quiet
robocat

1
У мене це є на певному етапі в реагуючому додатку, і це не працює.
FMD

1

Ненавмисне масштабування, як правило, відбувається, коли:

  • Користувач двічі торкається компонента інтерфейсу
  • Користувач взаємодіє з вікном перегляду за допомогою двох або більше цифр (прищіпка)

Щоб запобігти подвійному поводженню, я знайшов два дуже простих способи вирішення:

<button onclick='event.preventDefault()'>Prevent Default</button>
<button style='touch-action: manipulation'>Touch Action Manipulation</button>

І те й інше заважає Safari (iOS 10.3.2) збільшити масштаб кнопки. Як ви бачите, один лише JavaScript, інший - лише CSS. Використовуйте відповідним чином.

Ось демонстрація: https://codepen.io/lukejacksonn/pen/QMELXQ

Я не намагався попередити поведінку прищіпок (поки що), перш за все тому, що я прагну не створювати інтерфейси з декількома сенсорними технологіями для Інтернету, а по-друге, я прийшов до думки, що, можливо, всі інтерфейси, включаючи вбудований інтерфейс програми, повинні бути "щипцем для збільшення" -займається місцями. Я б все-таки намагався уникати користувачеві цього робити, щоб зробити ваш інтерфейс доступним для них за будь-яку ціну.


1

Знайдено цю просту роботу, яка, як видається, запобігає подвійному клацанню для збільшення:

    // Convert touchend events to click events to work around an IOS 10 feature which prevents
    // developers from using disabling double click touch zoom (which we don't want).
    document.addEventListener('touchend', function (event) {
        event.preventDefault();
        $(event.target).trigger('click');
    }, false);

1

Як вимагається, я передав свій коментар у відповідь, щоб люди могли його схвалити:

Це працює 90% часу для iOS 13:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no, shrink-to-fit=no" />

і

<meta name="HandheldFriendly" content="true">


0

Усі вищеперелічені відповіді я перевірив на практиці на своїй сторінці в iOS (iPhone 6, iOS 10.0.2), але не мав успіху. Це моє робоче рішення:

$(window).bind('gesturestart touchmove', function(event) {
    event = event.originalEvent || event;
    if (event.scale !== 1) {
         event.preventDefault();
         document.body.style.transform = 'scale(1)'
    }
});

На жаль, це працює лише тоді, коли ваша сторінка ідеально підходить, а не тоді, коли у вас є вміст, який можна прокручувати
взуття

Хм. На мій досвід, це чудово працює із вмістом, який можна прокручувати (iOS 10.3).
jeff_mcmahan

0

це працювало для мене:

document.documentElement.addEventListener('touchmove', function (event) {
    event.preventDefault();
}, false);

Я спробував це, це запобігло прискореному масштабуванню, проте воно вимикає сенсорну прокрутку вікна перегляду, тому ви більше не можете прокручувати сторінку вгору та вниз.
TGR
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.