cordova 防止页面在焦点切换时滚动

dgtucam1  于 2022-11-15  发布在  其他
关注(0)|答案(6)|浏览(190)

我是新的移动的网络/开发。我的应用程序是使用jquery-mobile,phonegap和指南针(scss)。
我的登录页面出现问题:
徽标和字段包含在标准的“div”容器中(data-role=“content”data-type=“vertical”)。背景是彩色的。
当焦点从登录字段切换到密码字段时,页面向上滑动,这是我不希望发生的。我希望我的徽标和字段保持原位,就像Skype iOS应用程序登录页面一样。
下面是发生的情况:

我尝试了几种技巧,试图阻止滚动事件,或强制页面滚动到0,0,都没有成功。
我现在正在考虑一个新的策略,也许使用顶部相对定位的标志和字段,并捕捉焦点事件滚动页面自己,在键盘上滑动(通过动画顶部相对定位坐标)。
虽然这似乎是可行的,但我想知道这是否是Skype iOS应用程序团队使用的工作方式。
欢迎对这种特殊情况下使用的技术提出任何建议!
干杯,
佛瑞德

iaqfqrcu

iaqfqrcu1#

我认为您希望直接在元素上调用焦点并使用'preventScroll'选项。
el.focus({preventScroll: true});

$('#el').focus((e) => {
  e.preventDefault();
  e.target.focus({preventScroll: true});
})

https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus

pieyvz9o

pieyvz9o2#

我还没有测试过这个,但是e.preventDefault()能阻止这个问题吗?通常你使用e.preventDefault()来阻止默认的滚动/拖动行为。

$(document).bind('focus', function(e){
  e.preventDefault();
});

或更好

$(element).bind('focus', function(e){
  e.preventDefault();
});

$(document).bind('touchstart', function(e){
  e.preventDefault();
});

输入字段会更好吗?

$(":input").live({
  focus: function(e) {
    e.preventDefault();
  }
});
sqxo8psd

sqxo8psd3#

我最终没有成功地找到任何编码解决方案来处理我的问题,但我注意到,一个chirurgical定位允许我在字段之间切换时frieze屏幕。
整个登录屏幕的可用空间不得超过键盘可见时的可用空间,即200像素。此外,为了防止切换字段时的滚动,最后一个输入字段的中心位置不得超过最大100像素。使用CSS可以在填充和边距上播放以达到所需的结果。
应该可以通过删除键盘“字段导航栏”来获得额外的垂直空间,但我也不知道如何做到这一点:/

0ve6wy6x

0ve6wy6x4#

我也遇到过类似的问题(点击/聚焦时页面滚动),我花了一段时间才找到解决方案,所以我在这里记录下来。
我有一个自定义的表单域,当点击它时,页面会滚动到顶部。结果发现,输入是通过position: absolute; top: -99999999px;隐藏的(因为如果你正确地隐藏了它,焦点事件就不起作用了)。这会把隐藏的输入放在页面的顶部。然后当我们点击标签,输入被聚焦时,页面会滚动到顶部。
我一直在搜索诸如“在焦点/点击时滚动到顶部”之类的内容,但我没有找到任何像样的内容。解决办法是使用right: -99999999px。我避免使用典型的left: -9999999px,因为很明显,在使用direction: rtl;时,这会影响网站

wfypjpf4

wfypjpf45#

focus()有一个preventScroll选项:
el.focus({preventScroll: true});
如果您必须支持不支持焦点选项的浏览器(IE11,Safari〈14?),请使用此polyfill

!function(){

    let supported = false;
    document.createElement('i').focus({
        get preventScroll() {
            supported = true;
        },
    });
    if (!supported) {
        let original = HTMLElement.prototype.focus;
        Element.prototype.focus = HTMLElement.prototype.focus = function(options){
            if (options.preventScroll) {
                const map = new Map();
                let p = this;
                while (p = p.parentNode) map.set(p, [p.scrollLeft, p.scrollTop]);
                original.apply(this, arguments);
                map.forEach(function(pos, el){
                    // todo: test: only if changed? does it trigger scroll?
                    // IE flickers
                    el.scrollLeft = pos[0]
                    el.scrollTop  = pos[1]
                });
            } else {
                original.apply(this, arguments);
            }
        }
    }

}();
laik7k3q

laik7k3q6#

在搜索了几个地方后,我还没有找到解决这个问题的最佳方法。我尝试了我自己的解决方案,它确实可以很好地防止滚动到焦点元素,所以我想在这里分享。
当用户关注我的目标元素时,我用position: fixed阻塞整个body。然后,我立即用setTimeout删除该阻塞(我利用事件循环)。
下面是我的代码示例

Javascript版本

第一个

jQuery版本

第一个
为了进行比较,下面是没有上述解决方法的版本
第一个

相关问题