如何使用 javascript/jquery 将焦点锁定在特定的 div

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7794957/
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-10-26 01:21:12  来源:igfitidea点击:

How to lock focus in a specific div using javascript/jquery

javascriptjquery

提问by Martin

I am developping some kind of modal popup using jQuery and I have some problems with the focus.

我正在使用 jQuery 开发某种模态弹出窗口,但我在焦点方面遇到了一些问题。

What happens right now, is that when I press the tab key, the focus goes to the controls hidden behind the popup.

现在发生的事情是,当我按下 Tab 键时,焦点转到隐藏在弹出窗口后面的控件。

Is there a way to force the focus to remain only on the controls in the popup window ?

有没有办法强制焦点只停留在弹出窗口中的控件上?

回答by Martin

Finally, I ended up with the following solution:

最后,我得到了以下解决方案:

When the window is opened, I save the tabindexes for all elements not in the popup window inside jQuery.data and I set the focus to the first element of the window.

当窗口打开时,我保存了不在 jQuery.data 内的弹出窗口中的所有元素的 tabindexes,并将焦点设置为窗口的第一个元素。

Then, for all those elements, I set the tabindex to -1 which prevents them from being accessed with the tab key.

然后,对于所有这些元素,我将 tabindex 设置为 -1,以防止使用 tab 键访问它们。

When the window is closed, I restore all tabindexes to their previous values.

当窗口关闭时,我将所有 tabindexes 恢复到它们以前的值。

回答by maxedison

There is. You basically need to listen for when the tab key is pressed, so that you can respond accordingly. Using jQuery, here's the general structure:

有。您基本上需要在按下 tab 键时监听,以便您可以做出相应的响应。使用 jQuery,这里是一般结构:

$(window).keydown(function(e){
    if(e.which ===9){ //it's the tab key!
        //do whatever you want here.

        e.preventDefault();
    }
});

You put your custom code where I commented do whatever you want here, and finish up by preventing the default action (such as jumping focus to a hidden control) with e.preventDefault;

您将自定义代码放在我评论的位置do whatever you want here,并通过阻止默认操作(例如将焦点跳转到隐藏控件)来结束e.preventDefault

回答by no.

You could always look into removing the default actions of the tabkey, there is a small tutorial on how to do this here.

你总是可以考虑去除的默认操作tab键,对如何做到这一点小教程在这里

However, that is for the enterand tabkey, but if you also look here, you will see that the tabkey is key number 9. So if we alter the code to just remove the default actions of the tabkey your line would be something similar to

但是,这是针对enterandtab键的,但如果您也查看此处,您将看到该tab键是键编号 9。因此,如果我们更改代码以仅删除tab键的默认操作,您的行将类似于

    if ( key == 9 ) { }

rather than

而不是

    if ( key == 3 || key == 9 || key == 13 ) { }

EDIT

编辑

Okay, since now you've stated you don't want to prevent the default action of the tabkey, but you still wish to stop that key from focusing on elements below the modal window.

好的,既然您已经声明不想阻止tab键的默认操作,但您仍然希望阻止该键聚焦在模态窗口下方的元素上。

The only thing I can think of now is, checking to see if the user is focused on your last field example 1/ example 2(you would link these to your last input/textarea/checkbox/radio). If so, you could do 1 of 2 things:

我现在唯一能想到的是,检查用户是否专注于您的最后一个字段示例 1/示例 2(您将这些链接到您的最后一个输入/文本区域/复选框/收音机)。如果是这样,您可以做以下两件事之一:

1) Use the above code and prevent the default action, thus, stopping the using from focusing on elements below the modal.

1) 使用上面的代码并阻止默认操作,从而阻止使用专注于模态下方的元素。

OR

或者

2) Focus back on the first field in your modal window, with first_field.focus();

2) 重新关注模式窗口中的第一个字段,使用 first_field.focus();

As far as I can see, by sticking with your requirements the second choice is the best option for you.

据我所知,通过坚持您的要求,第二个选择是您的最佳选择。

回答by Dave Mackintosh

Try here. Just prevent the user from pressing tab, or you'll have to loop through your fields and set tab indexes on them.

试试这里。只是防止用户按 Tab,否则您将不得不遍历您的字段并在它们上设置 Tab 索引。

回答by ethermal

I use a generic on focus event added to all input tags, when the event gets fired I determine the parent div's z-index if it is above a pre-determined threshold (9950 for example) then I allow the focus, if below I prevent focus. To prevent focus I do this by finding a control within the proper div and calling .focus() on that item.

我使用添加到所有输入标签的通用 on focus 事件,当事件被触发时,我确定父 div 的 z-index 如果它高于预先确定的阈值(例如 9950)然后我允许焦点,如果低于我阻止重点。为了防止焦点,我通过在适当的 div 中找到一个控件并在该项目上调用 .focus() 来做到这一点。

pseudo code below.

下面的伪代码。

$('input').bind('focus', function() 
{ 
 if ($(this).parents('div:first').css('z-index') <  9950) 
 {
    //prevent focus here
    //usually by finding a suitable target and setting focus
   $('input:first', $('.myModalClass')).focus(); 
 }
}); 

ps. Also set the tabindex on the items so that the items within your "modal" window are right after each other in the tab index. just makes things a little cleaner

附:还要在项目上设置选项卡索引,以便“模式”窗口中的项目在选项卡索引中紧随其后。只是让事情更干净一点

回答by spirytus

I had similar problem and created this tiny jQUeryUI plugin. Use it simply (in multiple places on a page if needed) and this will make TAB or shift+TAB iterate only inside of .someGroup wrapper.

我遇到了类似的问题并创建了这个小小的 jQUEryUI 插件。简单地使用它(如果需要,可以在页面上的多个位置),这将使 TAB 或 shift+TAB 仅在 .someGroup 包装器内部迭代。

$(".someGroup").tabGuard();

$(".someGroup").tabGuard();

More in here and I hope it will help someone:

更多在这里,我希望它会帮助某人:

http://tomaszegiert.seowebsolutions.com.au/tabguard/index.htm

http://tomaszegiert.seowebsolutions.com.au/tabguard/index.htm

回答by Mwr247

I think I might have a better solution to your problem that doesn't involve disabling tab or having to track/disable other elements. It does require jQueryUI though.

我想我可能有更好的解决方案来解决您的问题,不涉及禁用选项卡或必须跟踪/禁用其他元素。不过它确实需要 jQueryUI。

<div id="modalBgCover">
    <div onfocus="$(this).next('div').find(':tabbable').last().focus();" tabindex="0"></div>
    <div id="modal">
        <input id="input1">
        <input id="input2">
    </div>
    <div onfocus="$(this).prev('div').find(':tabbable').first().focus();" tabindex="0"></div>
<div>

What this does is creates two tabbable (but without content, so not visible) divs which take and redirect focus.

这样做是创建两个可选项卡(但没有内容,因此不可见)的 div,它们获取和重定向焦点。

Tabbing off the last input and into the bottom div will throw focus back to the first tabbable element inside the modal, and likewise shift+tabbing to the top div will throw focus back to the bottom input in the modal.

将最后一个输入移回底部 div 会将焦点抛回到模态内的第一个可制表元素,同样,shift+tabbing 到顶部 div 会将焦点抛回模态中的底部输入。

The modalBgCover overlays the page with a semitransparent layer, preventing clicks from getting through.

modalBgCover 用半透明层覆盖页面,防止点击通过。

回答by walv

I have implemented mini-framework based on gather knowledge including answers in this post.

我已经实现了基于收集知识的迷你框架,包括这篇文章中的答案。

It uses JQuery UI.

它使用 JQuery UI。

Improvements are welcome.

欢迎改进。

Here is framework object:

这是框架对象:

var TabLim = {};

TabLim.activate = function(el) {
    TabLim.deactivate();

    TabLim._el = el;

    $(window).on('keydown', TabLim._handleTab);

    return TabLim;
};

TabLim.deactivate = function() {
    TabLim._el = null;

    // detach old focus events
    TabLim._detachFocusHandlers();

    TabLim._els = null;
    TabLim._currEl = null;

    $(window).off('keydown', TabLim._handleTab);

    return TabLim;
};

TabLim.setFocus = function(prev) {
    // detach old focus events
    TabLim._detachFocusHandlers();

    // scan for new tabbable elements
    var tabbables = TabLim._el.find(':tabbable');
    TabLim._els = [];

    // wrap elements in jquery
    for ( var i = 0; i < tabbables.length; i++) {
        var el = $(tabbables[i]);
        // set focus listener on each element
        el.on('focusin', TabLim._focusHandler);
        TabLim._els.push(el);
    }

    // determine the index of focused element so we will know who is
    // next/previous to be focused
    var currIdx = 0;
    for ( var i = 0; i < TabLim._els.length; i++) {
        var el = TabLim._els[i];

        // if focus is set already on some element
        if (TabLim._currEl) {
            if (TabLim._currEl === el[0]) {
                currIdx = i;

                prev ? currIdx-- : currIdx++;
                break;
            }

        } else {
            // focus is not set yet.
            // let's set it by attribute "autofocus".
            if (el.attr('autofocus') !== undefined) {
                currIdx = i;
                break;
            }
        }
    }

    if (currIdx < 0) {
        currIdx += TabLim._els.length;
    }
    if (TabLim._els.length) {
        TabLim._els[Math.abs(currIdx % TabLim._els.length)].focus();
    }

    return TabLim;
};

TabLim._handleTab = function(e) {
    if (e.which === 9) {
        e.preventDefault();

        TabLim.setFocus(e.shiftKey);
    }
};

TabLim._focusHandler = function(e) {
    TabLim._currEl = e.currentTarget;
};

TabLim._detachFocusHandlers = function() {
    if (TabLim._els) {
        for ( var i = 0; i < TabLim._els.length; i++) {
            TabLim._els[i].off('focusin', TabLim._focusHandler);
        }
    }
};

How to use it:

如何使用它:

1) to activate to limit focus on specific div

1) 激活以限制对特定 div 的关注

TabLim.activate($('.yourDic')).setFocus();

2) to deactivate

2) 停用

TabLim.deactivate();

回答by Joel Lowther

When you open your modal popup window if your trying to just get the focus on the first input when they initially press the "tab" key then a very simple solution would be to put the focus on the first input in your modal popup window then simply apply a .blur() to that same input. Then when you hit "tab" it will begin the focus on that form.

当您打开模态弹出窗口时,如果您试图在他们最初按下“tab”键时将焦点放在第一个输入上,那么一个非常简单的解决方案是将焦点放在模态弹出窗口中的第一个输入上,然后简单地将 .blur() 应用于相同的输入。然后当您点击“标签”时,它将开始关注该表单。

$("#modalTestInput").focus();
$("#modalTestInput").blur();

If you're trying to remove any ability to focus on the inputs behind the modal popup window then your solution to apply a tabindex = "-1"to the inputs outside of your modal popup is definitely the way to go.

如果您试图消除任何专注于模态弹出窗口后面的输入的能力,那么将 a 应用于模态弹出窗口tabindex = "-1"之外的输入的解决方案绝对是要走的路。

Just thought you may be interested in a simpler solution.

只是认为您可能对更简单的解决方案感兴趣。