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

时间:2011-10-17 14:05:46

标签: javascript jquery

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

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

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

9 个答案:

答案 0 :(得分:1)

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

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

        e.preventDefault();
    }
});

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

答案 1 :(得分:1)

您可以随时查看删除tab键的默认操作,有一个关于如何执行此操作的小教程here

但是,这适用于entertab密钥,但如果您还查看here,则会看到tab密钥是密钥号9。所以如果我们更改代码只是删除tab键的默认操作,那么您的行将类似于

    if ( key == 9 ) { }

而不是

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

修改

好的,既然你已经声明你不想阻止tab键的默认动作,但是你仍然希望停止该键来关注模态窗口下方的元素。

我现在唯一能想到的是,检查用户是否专注于您的上一个字段example 1 / example 2(您可以将这些链接到您的上一个输入/ textarea /复选框/无线电)。如果是这样,你可以做两件事之一:

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

OR

2)使用first_field.focus();

重新关注模态窗口中的第一个字段

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

答案 2 :(得分:1)

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

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

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

当窗口关闭时,我将所有tabindex恢复为之前的值。

答案 3 :(得分:0)

试试here。只是阻止用户按Tab键,或者你必须遍历你的字段并在它们上设置标签索引。

答案 4 :(得分:0)

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

下面的伪代码。

$('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。同时在项目上设置tabindex,以便“模态”窗口中的项目在选项卡索引中相互正确。只是让事情变得更清洁

答案 5 :(得分:0)

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

$( “someGroup”)tabGuard();

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

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

答案 6 :(得分:0)

我想我可能有更好的解决方案,不涉及禁用标签或必须跟踪/禁用其他元素。它确实需要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>

这样做会创建两个可以捕获并重定向焦点的可列表(但没有内容,因此不可见)div。

选中最后一个输入并进入底部div会将焦点返回到模态内的第一个tabbable元素,同样shift + tabbing到顶部div会将焦点返回到模态中的底部输入。

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

答案 7 :(得分:0)

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

它使用JQuery UI。

欢迎改进。

这是框架对象:

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);
        }
    }
};

如何使用它:

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

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

2)停用

TabLim.deactivate();

答案 8 :(得分:0)

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

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

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

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