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


当前回答

我找不到干净的方法,但这里有一个黑客。。。

1) 我注意到mouseover事件发生在缩放之前,但缩放发生在mousedown或focus事件之前。

2) 您可以使用javascript动态更改META视口标记(请参阅使用javascript启用/禁用iPhone safari上的缩放?)

因此,请尝试以下操作(如jquery所示):

$("input[type=text], textarea").mouseover(zoomDisable).mousedown(zoomEnable);
function zoomDisable(){
  $('head meta[name=viewport]').remove();
  $('head').prepend('<meta name="viewport" content="user-scalable=0" />');
}
function zoomEnable(){
  $('head meta[name=viewport]').remove();
  $('head').prepend('<meta name="viewport" content="user-scalable=1" />');
}

这绝对是一个黑客。。。在某些情况下,mouseover/down并不总是捕捉入口/出口,但它在我的测试中运行良好,是一个坚实的开始。

其他回答

我最近(今天:D)不得不整合这种行为。为了不影响原始设计字段,包括combo,我选择在字段的焦点处应用转换:

input[type="text"]:focus, input[type="password"]:focus,
textarea:focus, select:focus {
  font-size: 16px;
}

您可以防止Safari在用户输入期间自动放大文本字段,而不禁用用户的缩放功能。只需添加最大比例=1,但忽略其他答案中建议的用户比例属性。

如果您在图层中有一个表单,如果缩放,它会“浮动”,这会导致重要的UI元素移出屏幕,这是一个值得选择的选项。

<meta name=“viewport”content=“width=设备宽度,初始比例=1,最大比例=1”>

即使有了这些答案,我也花了三天的时间才弄清楚到底发生了什么,我可能在未来再次需要解决方案。

我的情况与所描述的略有不同。

我在页面的一个div中有一些内容可编辑的文本。当用户单击一个不同的div(一个排序按钮)时,我自动选择了contenteditable div中的一些文本(之前已保存并清除的选择范围),对该选择运行一个富文本execCommand,然后再次清除。

这使我能够根据用户与页面上其他地方的颜色分隔符的交互无形地更改文本颜色,同时保持选择的正常隐藏状态,让他们在适当的上下文中看到颜色。

好吧,在iPad的Safari上,单击颜色分区会导致屏幕上的键盘出现,我所做的一切都不会阻止它。

我终于弄明白iPad是如何做到这一点的。

它监听触发可编辑文本选择的触摸开始和触摸结束序列。

当这种组合发生时,它会显示屏幕键盘。

实际上,它在放大可编辑文本的同时展开基础页面。我花了一天时间才明白我看到了什么。

因此,我使用的解决方案是拦截这些特定颜色div上的touchstart和touchend。在这两个处理程序中,我停止传播和冒泡,并返回false。但在touchend事件中,我触发的行为与单击触发的行为相同。

所以,在之前,Safari触发了我认为是“touchstart”、“mousedown”、“touchend”、“mouseup”、“click”的操作,因为我的代码,一个文本选择,按照这个顺序。

由于拦截而产生的新序列只是文本选择。在Safari处理和执行键盘操作之前,其他所有内容都会被拦截。touchstart和touchend拦截也防止触发鼠标事件,在上下文中这是完全正常的。

我不知道更简单的方法来描述这一点,但我认为这里有它很重要,因为我在第一次遇到这个问题的一小时内就找到了这个线索。

我有98%的把握,同样的修复方法也适用于输入框和其他任何东西。拦截触摸事件并单独处理它们,而不让它们传播或冒泡,并考虑在微小超时后进行任何选择,以确保Safari不会将该序列识别为键盘触发器。

在Angular中,您可以使用指令来防止IOS设备上的焦点缩放。没有保留可访问性的元标记。

import { Directive, ElementRef, HostListener } from '@angular/core';

const MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX = 16;

@Directive({ selector: '[noZoomiOS]' })

export class NoZoomiOSDirective {
  constructor(private el: ElementRef) {}

@HostListener('focus')
  onFocus() {
    this.setFontSize('');
  }

@HostListener('mousedown')
  onMouseDown() {
    this.setFontSize(`${MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX}px`);
  }

private setFontSize(size: string) {
  const { fontSize: currentInputFontSize } = window.getComputedStyle(this.el.nativeElement, null);

  if (MINIMAL_FONT_SIZE_BEFORE_ZOOMING_IN_PX <= +currentInputFontSize.match(/\d+/)) {
      return;
   }

  const iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
  iOS 
     && (this.el.nativeElement.style.fontSize = size);
 }
}

在*.module.ts中声明后,可以像这样使用<input noZoomiOS>

我看了多个答案\

在元标签中设置最大比例=1的答案在iOS设备上运行良好,但在Android设备上禁用缩放功能。设置字体大小的字体:16px;onfocus对我来说太粗糙了。

所以我编写了一个JS函数来动态更改元标记。

var iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
if (iOS)
    document.head.querySelector('meta[name="viewport"]').content = "width=device-width, initial-scale=1, maximum-scale=1";
else
    document.head.querySelector('meta[name="viewport"]').content = "width=device-width, initial-scale=1";