Мне пришлось «исправить» проблему автоматического увеличения в элементах управления формы для веб-сайта Голландского университета (в котором использовались 15px в элементах управления формой) Я выдвинул следующий набор требований:
- пользователь все еще должен иметь возможность увеличить
- размер шрифта должен оставаться прежним
- без вспышек временного различного стиля
- нет требований jQuery
- должен работать на новейшей iOS и не препятствовать любой другой комбинации ОС / устройства
- если возможно, никаких магических таймаутов, а при необходимости правильно сбрасывать таймеры
Это то, что я до сих пор придумал:
/*
NOTE: This code overrides the viewport settings, an improvement would be
to take the original value and only add or change the user-scalable value
*/
// optionally only activate for iOS (done because I havn't tested the effect under other OS/devices combinations such as Android)
var iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform)
if (iOS)
preventZoomOnFocus();
function preventZoomOnFocus()
{
document.documentElement.addEventListener("touchstart", onTouchStart);
document.documentElement.addEventListener("focusin", onFocusIn);
}
let dont_disable_for = ["checkbox", "radio", "file", "button", "image", "submit", "reset", "hidden"];
//let disable_for = ["text", "search", "password", "email", "tel", "url", "number", "date", "datetime-local", "month", "year", "color"];
function onTouchStart(evt)
{
let tn = evt.target.tagName;
// No need to do anything if the initial target isn't a known element
// which will cause a zoom upon receiving focus
if ( tn != "SELECT"
&& tn != "TEXTAREA"
&& (tn != "INPUT" || dont_disable_for.indexOf(evt.target.getAttribute("type")) > -1)
)
return;
// disable zoom
setViewport("width=device-width, initial-scale=1.0, user-scalable=0");
}
// NOTE: for now assuming this focusIn is caused by user interaction
function onFocusIn(evt)
{
// reenable zoom
setViewport("width=device-width, initial-scale=1.0, user-scalable=1");
}
// add or update the <meta name="viewport"> element
function setViewport(newvalue)
{
let vpnode = document.documentElement.querySelector('head meta[name="viewport"]');
if (vpnode)
vpnode.setAttribute("content",newvalue);
else
{
vpnode = document.createElement("meta");
vpnode.setAttribute("name", "viewport");
vpnode.setAttribute("content", newvalue);
}
}
Некоторые заметки:
- Обратите внимание, что до сих пор я тестировал его только на iOS 11.3.1, но скоро опробую его на нескольких других версиях
- Использование событий focusIn означает, что для него требуется как минимум iOS 5.1 (но я считаю, что сайты, которые мы создаем, работающие на версиях iOS старше 9, как крутой бонус)
- Использование делегирования события, потому что на многих сайтах, над которыми я работаю, есть страницы, которые могут динамически создавать элементы управления формой
- Установка для eventListeners элемента html (documentElement), чтобы не нужно было ждать, пока тело станет доступным (не нужно беспокоиться о проверке, находится ли документ в состоянии готовности / загрузки, или нет необходимости ждать события DOMContentLoaded)