21

我是移动网络/开发的新手。我的应用程序正在使用 jquery-mobile、phonegap 和 Compass (scss)。

我的登录页面有问题:

徽标和字段包含在标准的“div”容器中(data-role="content" data-type="vertical")。背景是彩色的。

当焦点从登录字段切换到密码字段时,页面向上滑动,这是我不希望发生的。我希望我的徽标和字段保持不变,就像 Skype iOS 应用程序登录页面一样。

这是发生的事情:

错误描述

我尝试了几种技巧,试图阻止滚动事件,或强制页面滚动到 0,0,但没有成功。

我现在正在考虑一种新策略,可能对徽标和字段使用顶部相对定位,并在键盘向上滑动时捕获焦点事件以自己滚动页面(通过动画顶部相对定位坐标)。

虽然这似乎可行,但我想知道这是否是 Skype iOS 应用程序团队使用的那种工作......

欢迎任何有关此特定案例中使用的技术的建议!

干杯,

弗雷德

4

5 回答 5

29

我认为您想直接将焦点放在元素上并使用“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

于 2018-06-08T21:44:05.110 回答
5

我还没有对此进行测试,但是 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();
  }
});
于 2012-10-06T17:07:41.923 回答
2

我最终没有成功地找到任何编码解决方案来处理我的问题,但我注意到一个整脊定位让我在字段之间切换时可以固定屏幕。

整个登录屏幕的可用空间不得超过键盘可见后的可用空间,即 200 像素。此外,为防止在切换字段时滚动,最后输入字段中心位置不得超过 100 像素。使用 CSS 可以在 padding 和 margin 上播放以获得所需的结果。

通过删除键盘“字段导航栏”应该可以获得额外的垂直空间,但我也不知道该怎么做:/

在此处输入图像描述

于 2012-10-27T15:59:42.180 回答
2

我有一个类似的问题(页面在点击/焦点上滚动),我花了一段时间才找到解决方案,所以我在这里记录它。

我有一个自定义表单字段,单击该字段会将页面滚动到顶部。结果是输入被隐藏了position: absolute; top: -99999999px;(因为如果你正确隐藏它,那么焦点事件就不起作用)。这将隐藏的输入放置在页面顶部。然后当我们点击标签并且输入被聚焦时,页面被滚动到顶部。

我正在寻找诸如“在焦点/点击时滚动到顶部”之类的东西,但我找不到任何像样的东西。解决方案是right: -99999999px改用。我避免使用典型的left: -9999999px,因为显然这会在使用时影响网站direction: rtl;

于 2019-09-02T15:12:41.750 回答
0

preventScrollfocus()有一个选项:
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);
            }
        }
    }

}();
于 2021-07-13T09:20:22.277 回答