我制作了一个HTML页面,其中有一个<input>标记,类型为“text”。当我在iPhone上使用Safari点击它时,页面会变大(自动缩放)。有人知道如何禁用此功能吗?


当前回答

正如许多其他答案已经指出的那样,这可以通过向元视口标记添加最大比例来实现。然而,这会导致在Android设备上禁用用户缩放功能。(自v10以来,它不会在iOS设备上禁用用户缩放。)

当设备为iOS时,我们可以使用JavaScript动态地向元视口添加最大比例。这实现了两全其美:我们允许用户缩放,并防止iOS缩放到聚焦的文本字段。

| maximum-scale             | iOS: can zoom | iOS: no text field zoom | Android: can zoom |
| ------------------------- | ------------- | ----------------------- | ----------------- |
| yes                       | yes           | yes                     | no                |
| no                        | yes           | no                      | yes               |
| yes on iOS, no on Android | yes           | yes                     | yes               |

代码:

const addMaximumScaleToMetaViewport = () => {
  const el = document.querySelector('meta[name=viewport]');

  if (el !== null) {
    let content = el.getAttribute('content');
    let re = /maximum\-scale=[0-9\.]+/g;

    if (re.test(content)) {
        content = content.replace(re, 'maximum-scale=1.0');
    } else {
        content = [content, 'maximum-scale=1.0'].join(', ')
    }

    el.setAttribute('content', content);
  }
};

const disableIosTextFieldZoom = addMaximumScaleToMetaViewport;

// https://stackoverflow.com/questions/9038625/detect-if-device-is-ios/9039885#9039885
const checkIsIOS = () =>
  /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

if (checkIsIOS()) {
  disableIosTextFieldZoom();
}

其他回答

我花了一段时间才找到它,但这是我找到的最好的代码。。。。。。http://nerd.vasilis.nl/prevent-ios-from-zooming-onfocus/

var $viewportMeta = $('meta[name="viewport"]');
$('input, select, textarea').bind('focus blur', function(event) {
$viewportMeta.attr('content', 'width=device-width,initial-scale=1,maximum-scale=' +        (event.type == 'blur' ? 10 : 1));
});

总之,答案是:将表单元素的字体大小设置为至少16px

下面是我在一个项目中使用的黑客:

select {
    font-size: 2.6rem; // 1rem = 10px
    ...
    transform-origin: ... ...;
    transform: scale(0.5) ...;
}

最终得到了我想要的初始样式和比例,但没有缩放焦点。

一条关于将字体大小设置为16px的顶级答案的评论询问了这是如何解决的,如果你想要更大/更小的字体怎么办。

我不知道你们所有人的情况,但使用px来调整字体大小并不是最好的方法,你应该使用它们。

我在我的响应网站上遇到了这个问题,我的文本字段大于16像素。我的表单容器设置为2em,输入字段设置为1.4em。在移动查询中,我根据视口更改html字体大小。由于默认的html是10,我的输入字段在桌面上计算为28px

为了取消自动缩放,我不得不将输入更改为1.6em。这将我的字体大小增加到32px。只是稍微高一点,几乎看不到。在我的iPhone 4和5上,我将html字体大小改为15像素(纵向),改回10像素(横向)。看起来像素大小的最佳点是48px,这就是为什么我从1.4em(42px)改为1.6em(48px)。

你需要做的事情是找到字体大小的最佳位置,然后将其转换为rem/em大小。

我不得不“修复”一个荷兰大学网站的表单控件自动缩放问题(表单控件中使用了15px)。我提出了以下一组要求:

用户必须仍然能够放大字体大小必须保持不变没有暂时不同风格的闪光无jQuery要求必须在最新的iOS上运行,不得妨碍任何其他OS/设备组合如果可能,没有魔法超时,如果需要,正确清除计时器

这是我到目前为止想到的:

/*
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(但我认为我们在早于9的iOS版本中创建的网站是一个很酷的奖励)使用事件委派,因为我工作的许多站点都有可能动态创建表单控件的页面将eventListeners设置为html元素(documentElement),这样就不必等待body变为可用(不需要检查文档是否已就绪/已加载状态或需要等待DOMContentLoaded事件)