javascript 如何防止iOS键盘推出的视图与CSS或JS屏幕

eqqqjvef  于 2023-01-24  发布在  Java
关注(0)|答案(7)|浏览(97)

我有一个响应式网页,当你点击一个按钮时,它会打开一个模态。当模态打开时,它被设置为使用固定位置占据整个页面的宽度和高度。模态中还有一个输入字段。
在iOS设备上,当输入字段被聚焦时,键盘打开。然而,当它打开时,它实际上将整个文档向上推,这样我的页面的一半就超出了视口的顶部。我可以确认实际的html标记本身已经被向上推以补偿键盘,并且它没有通过CSS或JavaScript发生。
以前有人见过这种情况吗?如果见过,有什么方法可以防止这种情况,或者在键盘打开后重新定位吗?这是一个问题,因为我需要用户能够看到模态顶部的内容,同时,我希望自动聚焦输入字段。

wqnecbli

wqnecbli1#

第一

<script type="text/javascript">
 $(document).ready(function() {
     document.ontouchmove = function(e){
          e.preventDefault();
          }
 });

那么这个

input.onfocus = function () {
    window.scrollTo(0, 0);
    document.body.scrollTop = 0;
}
b0zn9rqh

b0zn9rqh2#

对于任何在React中遇到这个问题的人,我已经设法修复了它,并采用了如下的@ankurJos解决方案:

const inputElement = useRef(null);

useEffect(() => {
  inputElement.current.onfocus = () => {
    window.scrollTo(0, 0);
    document.body.scrollTop = 0;
  };
});

<input ref={inputElement} />
vwkv1x7d

vwkv1x7d3#

我为此挣扎了一段时间,我找不到适合我的东西。
我最后做了一些JavaScript黑客使它工作。
我发现,如果输入元素在屏幕的上半部分,Safari就不会推送视口,这就是我的小技巧的关键所在:
我拦截输入对象上的focus事件,并将焦点重定向到一个不可见的对象上(通过transform: translateX(-9999px)),然后一旦键盘出现在屏幕上(通常为200ms左右),我就触发原始元素上的focus事件,该元素后来在屏幕上显示为动画。
这是一种复杂的互动,但效果很好。

function ensureOffScreenInput() {
  let elem = document.querySelector("#__fake_input");
  if (!elem) {
    elem = document.createElement("input");
    elem.style.position = "fixed";
    elem.style.top = "0px";
    elem.style.opacity = "0.1";
    elem.style.width = "10px";
    elem.style.height = "10px";
    elem.style.transform = "translateX(-1000px)";
    elem.type = "text";
    elem.id = "__fake_input";
    document.body.appendChild(elem);
  }
  return elem;
}

var node = document.querySelector('#real-input')
var fakeInput = ensureOffScreenInput();

function handleFocus(event) {
  fakeInput.focus();

  let last = event.target.getBoundingClientRect().top;

  setTimeout(() => {
    function detectMovement() {
      const now = event.target.getBoundingClientRect().top;
      const dist = Math.abs(last - now);

      // Once any animations have stabilized, do your thing
      if (dist > 0.01) {
        requestAnimationFrame(detectMovement);
        last = now;
      } else {
        event.target.focus();
        event.target.addEventListener("focus", handleFocus, { once: true });
      }
    }
    requestAnimationFrame(detectMovement);
  }, 50);
}

node.addEventListener("focus", handleFocus, { once: true });

就我个人而言,我在一个苗条的动作中使用这段代码,它在我的苹果Map的苗条PWA克隆中运行得非常好。
Video of it working in a PWA clone of Apple Maps
你会注意到在视频中,当输入到视口上半部分的动画稳定下来后,自动完成功能发生了变化,这就是焦点切换。
这种方法的唯一缺点是,原始实现上的焦点处理程序将运行两次,但是有一些方法可以通过元数据来解决这个问题。

rekjcdws

rekjcdws4#

如果不想滚动到顶部(0,0),也可以执行此操作

window.scrollBy(0, 0)
af7jpaap

af7jpaap5#

const handleResize = () => {
  document.getElementById('header').style.top = window.visualViewport.offsetTop.toString() + 'px'
}

if (window && window.visualViewport) visualViewport.addEventListener('resize', handleResize)

来源:https://rdavis.io/articles/dealing-with-the-visual-viewport

ldfqzlk8

ldfqzlk86#

在某些情况下,这个问题可以通过重新聚焦输入元素来缓解。

input.onfocus = function () {
  this.blur();
  this.focus();
}
qnakjoqk

qnakjoqk7#

IOS8和Safari bowsers在页面加载后的input. focus()行为相同。它们都缩放到元素并弹出键盘。(不太确定这是否有帮助,但你试过这样做吗?)

    • HTML IS**
<input autofocus>
    • JS是**
for (var i = 0; i < 5; i++) {
document.write("<br><button onclick='alert(this.innerHTML)'>" + i + "</button>");
}

//document.querySelector('input').focus();
    • 中央支助组**
button {
width: 300px;
height: 40px;
}

此外,您还必须使用用户代理解决方案,您可以将其用于所有IOS版本

if (!/iPad|iPhone|iPod/g.test(navigator.userAgent)) {
element.focus();
}

相关问题