【问题标题】:How to stop browser auto scrolling containers on focus changes如何在焦点更改时停止浏览器自动滚动容器
【发布时间】:2013-09-01 23:07:22
【问题描述】:

当您在浏览器中的输入字段之间切换时,浏览器将自动滚动最近的父容器以将下一个焦点字段放置在视图中。

简单的 JSFiddle:http://jsfiddle.net/TrueBlueAussie/pxyXZ/1/

$('.section').eq(6).find('input').focus();

例如,如果您打开上面的小提琴,它会在黄色窗口的底部选择“Sample item 7”。如果按 Tab,“Sample text 8”字段会向上跳到父窗口的中间。

显然这对于​​普通网站来说是件好事,但我有一个自定义滚动容器,我可以在其中手动定位和滚动所有内容。我正在跟踪焦点变化并将使用动量滚动条将其显示出来,但是如何禁用网络浏览器的默认滚动行为?很高兴接受 CSS、Javascript 或 JQuery 解决方案。 p>

【问题讨论】:

  • 我首先想到的是使用keyUp 检测来注册选项卡,查看下一个输入是否超出“窗口”,然后使用带有$(':focus').parent().next().find('input').focus() 的自定义滚动条作为回调。你的动量卷轴是什么?是否允许回调函数?
  • @PlantTheIdea:我根据这篇文章写了自己的动量滚动条:ariya.ofilabs.com/2011/10/…,我确实有回调。
  • 好的,提供了答案。它是通用的,因为我没有真正可以使用的代码,但一般要点是您不想禁用浏览器的滚动行为,您希望将焦点更改推迟到您执行自己的滚动之后。这将允许您根据需要控制滚动。

标签: javascript jquery browser html-input tabbing


【解决方案1】:

这只是基于我上面的评论:

$('input').on('keyup',function(e){
    if(e.keyCode === 9) {
        var $this = $(this);

        // (do your scroll thing here
        // ..., function(){
            $this.parent().next().find('input').focus();
        // });
    }
});

只要回调时机正确,这只会在您滚动后改变焦点。您需要自己发挥作用来确定要滚动到的内容,但这应该会为您提供所需的焦点行为。

【讨论】:

  • 必须在keydown 上,因为焦点更改发生在keydown,而不是keyup。还需要在 shift-tab 上反转方向并为下一个输入使用更通用的选择器(但除了您在正确轨道上的所有内容)。几乎完成了你的想法。谢谢:)
  • 是的,我的意思是我认为它需要一些调整,这是一个更普遍的想法。希望它对你有用!
  • +1 给了我正确的想法。已发布确切的解决方案,因为它可能对其他人有所帮助。感谢您为我指明正确的方向。
【解决方案2】:

事实证明,由于事件以错误的顺序发生,因此您无法平滑滚动以进行焦点更改。在设置焦点之前,当它将字段滚动到视图中时,您会遇到可怕的延迟。更好地移动屏幕上的项目,或超快滚动,是我们所希望的。

正如 PlantTheIdea (+1'ed) 所建议的,您需要抓住 TAB 键并找到下一个可聚焦的项目,将其置于视野中,然后将焦点设置为它。

实际上有很多问题需要解决:

  • 焦点发生在 TAB 键下(不是键上)上。
  • 仅匹配非隐藏输入(许多网络应用程序都有隐藏字段,如果您尝试将它们集中起来,它们会爆炸)。
  • 允许选择标签关闭页面上的第一个或最后一个项目(否则浏览器将失去标签到其地址栏的能力)
  • 使用e.keyCode || e.which 允许使用旧版浏览器
  • 在文档级别捕获事件以允许在滚动区域之外的其他输入的情况下,使其进入滚动区域(第一个或最后一个输入)。

最终代码如下所示:

$(document).on('keydown', ':focus', function (event)
{
    if ((event.keyCode || event.which) == 9)
    {
        var $inputs = $(":input:not(hidden)")
        var index = $inputs.index(this);
        // Index previous or next input based on the shift key
        index += event.shiftKey ? -1 : 1;
        // If we are in the range of valid inputs (else browser takes focus)
        if (index >= 0 && index < $inputs.length)
        {
            var $next = $inputs.eq(index);
            event.preventDefault();
            // Move, not scroll, to the next/prev item....
            MoveIntoView($next);
            $next.focus();
            return false;
        }
    }
});

【讨论】:

  • 请注意,您可以使用tabindex 属性显式声明制表符处理的顺序。这应该有助于隐藏输入部分,并且还允许检查页面上的第一项或最后一项(例如,if($(this).attr('tabindex') &lt; 10))。
  • @PlantTheIdea: tabindex 并非在所有浏览器中都得到正确支持,但在这种情况下,我们只想使用创建的顺序,因为我们的内容是动态生成的(包括部分页面)我不想要除非绝对需要,否则明确指定 Tab 键顺序。感谢您指出这一点,因为上面的代码当前将忽略任何现有的 tabindex 值。就隐藏输入而言,最好还是忽略/排除它们。我们做了很多充满隐藏输入的 MVC 应用程序。干杯
猜你喜欢
  • 2018-05-27
  • 1970-01-01
  • 2012-09-11
  • 2011-10-25
  • 2017-08-14
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多