jQuery 更改焦点表单元素 ipad web 应用程序时禁用滚动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6740253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 21:19:59  来源:igfitidea点击:

Disable scrolling when changing focus form elements ipad web app

jqueryformsipadscrollsafari

提问by Andrew Samuelsen

I have a web app. I'm trying to disable/prevent the scrolling that occurs when you focus on different form inputs (i.e. the scrolling that occurs as you advance through input elements in a form).

我有一个网络应用程序。我试图禁用/防止在您关注不同表单输入时发生的滚动(即在您浏览表单中的输入元素时发生的滚动)。

I've already disabled scrolling with this:

我已经禁用了滚动:

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

To add a little more info - I have a few "slides" that my page consists of. Each are 768x1024 and they are "stacked" on the page (i.e. the page is 768x3072 [1024*3=3072]) and when you click a link I'm using scrollTo jquery plugin to scroll to the next "slide" and .focus()on an input element.

要添加更多信息 - 我的页面包含一些“幻灯片”。每个都是 768x1024 并且它们在页面上“堆叠”(即页面是 768x3072 [1024*3=3072]),当您单击链接时,我正在使用 scrollTo jquery 插件滚动到下一个“幻灯片”并.focus()在输入元素。

Does anyone know how to do this?

有谁知道如何做到这一点?

采纳答案by Paul Greyson

I've found that in UIWebView, document.body is also sometimes moved. So I use:

我发现在 UIWebView 中,document.body 有时也会被移动。所以我使用:

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

回答by Paul Lan

Ooops, the window.scrollTosuggested is kinda lousy and make things unpredictable.

哎呀,window.scrollTo建议有点糟糕,让事情变得不可预测。

Try this better solution:

试试这个更好的解决方案:

jQuery('body').bind('focusin focus', function(e){
  e.preventDefault();
})

Or, just hook your input:

或者,只需挂钩您的输入:

jQuery('input.your-input-class').bind('focusin focus', function(e){
  e.preventDefault();
})

Why? Browsers may scroll the focused form element into view by default on 'focusin' event fired (Firefox has a bug, so hook on focus instead). So, just tell them don't do that explicitly.

为什么?默认情况下,浏览器可能会在触发 'focusin' 事件时将聚焦的表单元素滚动到视图中(Firefox 有一个错误,所以改为钩住焦点)。所以,只要告诉他们不要明确地这样做。

BTW, if the focusevent is triggered by element.focus()in your code, then even the upon solution would not be functional.

顺便说一句,如果focus事件是element.focus()在您的代码中触发的,那么即使是 on 解决方案也不会起作用。

So, a solution to that would be replace you focustrigger to select, i.e.

所以,解决这个问题的方法是将你的focus触发器替换为select,即

element.select()

other than element.focus()

以外 element.focus()

If you don't like the element.select()approach since it will selectthe text inside the input element, then try to create a Range objectof the input element text and collapse it if you will, sorry for no time to try that at this moment.

如果您不喜欢这种element.select()方法,因为它将select输入元素中的文本,然后尝试创建一个Range object输入元素文本并将其折叠(如果愿意),抱歉现在没有时间尝试。

回答by Dominik

To prevent the browser from scrolling to the element you move focus to I use jQuerys oneevent listener. Right before I move the focus to the element we add the listener to the scrollevent and counter scroll. The event listener is than removed by jQuery.

为了防止浏览器滚动到您将焦点移到的元素,我使用了 jQueryone事件侦听器。在我将焦点移到元素之前,我们将侦听器添加到scroll事件和计数器滚动中。事件侦听器随后被 jQuery 删除。

var oldScroll = $(window).scrollTop();

$( window ).one('scroll', function() {
    $(window).scrollTop( oldScroll ); //disable scroll just once
});

$('.js-your-element').focus();

This way seems simple, effective to me and works great in all tests I have done.

这种方式对我来说似乎简单、有效,并且在我所做的所有测试中都非常有效。

Hope it helps someone.

希望它可以帮助某人。

回答by Mischa Magyar

If you do not want the input to be editable the answer from kpozin works fine. But as soon as you remove the readonlyattribute onfocusor onclickthe input field scrolls in focus again.

如果您不希望输入可编辑,则 kpozin 的答案可以正常工作。但是一旦您删除readonly属性onfocusonclick输入字段再次滚动焦点。

What really helps and does not impact focus or ability to enter text is adding onFocus="window.scrollTo(0, 0);"to the input elements.

真正有帮助而不影响焦点或输入文本能力的是添加onFocus="window.scrollTo(0, 0);"到输入元素。

Of course you have to guarantee that the relevant input is not covered by the onscreen keyboard!

当然你要保证相关的输入不被屏幕键盘覆盖!

See also this post: Preventing an <input> element from scrolling the screen on iPhone?

另请参阅这篇文章:防止 <input> 元素在 iPhone 上滚动屏幕?

回答by panchoLopez

Update on this - I've seen the window.scroll(0,0)solution in a couple of different places but it seemed to just make it worse. I have multiple inline text inputs on my page so when moving focus between them the automatic up and down scrolling in Safari made the page almost unusable, especially in landscape orientation.

对此进行更新 - 我已经window.scroll(0,0)在几个不同的地方看到了解决方案,但它似乎只会让情况变得更糟。我的页面上有多个内联文本输入,因此在它们之间移动焦点时,Safari 中的自动上下滚动使页面几乎无法使用,尤其是在横向时。

After fighting iOS 8 for a week on this I found this stops the scrolling. This works when changing focus from one element to another as you need to attach the onblur event to something:

在为此与 iOS 8 进行了一周的斗争后,我发现这会停止滚动。这在将焦点从一个元素更改为另一个元素时有效,因为您需要将 onblur 事件附加到某物上:

var moveFocus = function (blurId, focusId) {
    var blurInput = document.getElementById(blurId);
    var focusInput = document.getElementById(focusId);
    if (blurInput && focusInput) {
        blurInput.onblur = function () {
            if (focusInput.setSelectionRange && focusInput.setSelectionRange()) {
                var len = focusInput.value.length;
                focusInput.setSelectionRange(len, len);
            }
            focusInput.focus();
        };
        focusInput.focus();
    };
};

回答by proxiblue

None of the provided solutions worked for me. Since the form that is grabbing the focus (and scrolling page initial display to said form) is below the fold, I simply added a fade-in to the form.

提供的解决方案都不适合我。由于获取焦点的表单(并将页面初始显示滚动到所述表单)位于折叠下方,因此我只是在表单中添加了淡入。

So I add a class name called fade-in, which corresponding css to display:none

所以我添加了一个名为 的类名fade-in,它对应的 css 到display:none

using jQuery I then simply do jQuery(".fade-in").fadeIn();after document ready, and the issue is gone.

使用 jQuery 我然后简单地jQuery(".fade-in").fadeIn();在文档准备好后做,问题就消失了。

This is obviously not limited to using jQuery. Vanilla js can be used for the fade.

这显然不仅限于使用 jQuery。Vanilla js 可用于淡入淡出。

回答by David Schumann

In case you are developing a mobile webapp with cordova, there is a plugin for that:

如果您正在使用cordova开发移动网络应用程序,则有一个插件:

The plugin that solved the problem for me was the Telerik Keyboard Plugin. It is using the basic UIWebView. Install the plugin

为我解决问题的插件是Telerik 键盘插件。它使用的是基本的 UIWebView。安装插件

cordova plugin add ionic-plugin-keyboard

And call this command after your app loaded:

并在您的应用程序加载后调用此命令:

cordova.plugins.Keyboard.disableScroll(true);

In case you are using the WKWebView, you can use e.g. this plugin

如果您使用的是 WKWebView,您可以使用例如这个插件

回答by tic

To "focus" without any scroll, you may use select. selectby default will select all of the text inside an input. To mimic focusbehavior and have the caret at the end of the input you can use:

要在没有任何滚动的情况下“聚焦”,您可以使用select. select默认情况下将选择输入中的所有文本。要模仿focus行为并在输入末尾添加插入符号,您可以使用:

var myInput = document.getElementById('my-input');
var length = myInput.value.length;  // Or determine the value of length any other way
myInput.select();
myInput.setSelectionRange(length, length);

回答by alex marmon

For whatever reason, it appears you can mitigate this by applying a keyframe animation to an autoFocused input container.

无论出于何种原因,您似乎可以通过将关键帧动画应用于自动聚焦输入容器来缓解这种情况。

function App() {
  const [isSearching, setIsSearching] = useState(false);

  return (
    <FixedContainer>
      {isSearching && (
        <Box>
          <Input autoFocus type="text" placeholder="click me" onBlur={() => setIsSearching(false)} />
        </Box>
      )}
    </FixedContainer>
  )
}

const fadeInKeyframes = keyframes`
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
`;

const Box = styled.div`
  animation-name: ${fadeInKeyframes};
  animation-duration: 0.1s;
  animation-timing-function: ease;
  animation-delay: 0s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-fill-mode: forwards;
  animation-play-state: running;
`;

https://stackblitz.com/edit/react-ios-input-scroll

https://stackblitz.com/edit/react-ios-input-scroll

Working example: https://react-ios-input-scroll.stackblitz.io

工作示例:https: //react-ios-input-scroll.stackblitz.io

回答by mhenry1384

This worked for me (using jQuery). It allows the scroll and then returns you to the proper position when you leave the input.

这对我有用(使用 jQuery)。它允许滚动,然后在您离开输入时将您返回到正确的位置。

    var saveScrollLeft;
    $("input, textarea")
        .focus(function () {
            clearTimeout(blurTimeoutId);
            saveScrollLeft = $("body").scrollLeft();
            })
        .blur(function () {
            // The user might be moving from one input to another, so we don't want to quickly scroll on blur.  Wait a second and see if they are off all inputs.
            blurTimeoutId = setTimeout(function () {
                $(window).scrollLeft(saveScrollLeft);
                }, 1000);
        });