当固定位置文本输入表单字段获得焦点时,如何防止滚动?

时间:2012-05-10 21:38:40

标签: android html css forms

我有一个移动网络应用程序,在一个位置显示一个对话框:固定元素覆盖整个屏幕。无论显示多少内容或页面滚动多远,覆盖元素都会使页面内容变暗,并且对话框会显示在其上面。对话框中有一个<input type="search />字段。

在Android上,当用户点击输入字段以使其获得焦点时,通常会(但不总是)出现一些非常不稳定的行为:

  • 出现软键盘,然后立即消失。
  • 底层页面(由叠加层覆盖)滚动几十个像素,有时向上,有时向下,有时在两个方向,有时重复。当输入字段失去焦点时也会发生这种情况。
  • 叠加元素瞬间向下和向右移动几个像素,沿着屏幕的顶部和左侧边缘显示底层内容。 (它会在不到一秒钟后返回。)

这是在内置浏览器的Android 2.3.4上。它也可能出现在其他Android版本上。

页面构造如下: (请记住,当页面包含足够的内容以允许滚动时,其中一些怪癖才会显示。)

<head>
  <style type="text/css">
    #menuoverlay {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 10;
    background-color: rgba(0,0,0,.75);
    text-align: center;
    }
    #menu {
    display: inline-block;
    margin-top: 1em;
    border: 3px solid #02b;
    border-radius: 8px;
    padding: 1ex;
    background-color: black;
    color: silver;
    }
  </style>
</head>

<body>
  <div id="menuoverlay">
    <div id="menu">
      ...menu items...
      ...menu items...
      <form action=""><input type="search"/></form>
    </div>
  </div>

  <div id="content">
    ...lots of stuff...
    ...lots of stuff...
    ...lots of stuff...
  </div>
<body>

还有其他人看过这种行为吗?你找到了预防它的方法吗?


在网上搜索引发了一些类似问题的报告。以下是我到目前为止所阅读内容的摘要:

  • 在许多Android设备上,内置浏览器显然不会像人们期望的那样使用WebKit的输入字段。相反,当html定义的字段获得焦点时,浏览器会尝试使用它单独创建的新文本小部件来覆盖它们。
  • 这些重复的文本字段通常会忽略css样式,创建一个效果,其中字段看起来样式直到它们获得焦点,然后突然恢复为系统默认样式。
  • Android浏览器通常无法正确定位这些重复字段。当放错位置时,它们有时是可见的,但有时只会移动焦点目标而没有任何视觉指示它们已移动。
  • 当输入字段的祖先元素包含transform: translate3d()-webkit-backface-visibilityposition: fixed等样式时,通常会显示这些问题。

以下是一些相关链接:

Android Browser textarea scrolls all over the place, is unusable

How can I style an HTML INPUT tag so it maintains CSS when focused on Android 2.2+?

Android 2.2/2.3’s Native Browser and Fixed Positioning

2 个答案:

答案 0 :(得分:12)

我设法通过在outline: none元素上设置input来阻止瞬间重叠移位。

当显示对话框时,我通过在html overflow: hidden上设置body,然后在隐藏对话框时再次将其删除,从而滚动并消失键盘以使其稳定下来。这有一个令人讨厌的副作用,重置页面的滚动位置,所以我保存并根据需要恢复它,并将所有这些hackery包装在条件中,以便它只在Android上运行。 (我希望我的Android用户在对话框打开时看到半透明叠加层下的页面内容发生变化时不会太分散注意力。)

有趣的是,我还能够通过在我的overlay元素上捕获touchstart事件并调用preventDefault()来阻止狂野页面滚动。这让我想知道所有这些疯狂是否是由这样的一系列事件引起的:

  • touchstart冒泡到文档根目录
  • 浏览器会看到放置了重复输入字段的touchstart
  • 浏览器将焦点放在输入字段
  • 软键盘似乎允许输入输入字段
  • 视口调整大小以容纳软键盘
  • 在触摸事件期间调整大小的视口看起来像是对浏览器的触摸拖动
  • 虚假拖动导致页面滚动并解除键盘

我最终没有抓住touchstart来解决问题,因为它阻止输入字段获得焦点,而从javascript调用focus()只是不起作用。我已经读过Android浏览器在输入字段上禁用focus()方法,这可以解释这种行为。也许这样做是因为它不适用于它在html定义的字段上创建的重复文本小部件。

答案 1 :(得分:0)

在我的情况下,“位置:固定;”不是问题,“vertical-align:center;”或“-webkit-box-align:center;”推回并关闭软键盘,使用“-webkit-box-align:start;”解决了我的问题。