jQuery UI焦点窃取

时间:2013-03-27 17:33:46

标签: jquery jquery-ui modal-dialog

每当我在下面的插入超链接文本输入中键入内容时,所有单词都将在其后面textarea。确定和取消按钮工作正常,但我无法专注于文本输入。

我们正在使用jQuery UI 1.10.1。它与之前版本的jQuery(1.8.x)运行良好。

enter image description here

我已经检查了jQuery背后的代码,并且在打开模态对话框时调用了以下方法:

_focusTabbable: function () {
    // Set focus to the first match:
    // 1. First element inside the dialog matching [autofocus]
    // 2. Tabbable element inside the content element
    // 3. Tabbable element inside the buttonpane
    // 4. The close button
    // 5. The dialog itself
    var hasFocus = this.element.find("[autofocus]");
    if (!hasFocus.length) {
        hasFocus = this.element.find(":tabbable");
    }
    if (!hasFocus.length) {
        hasFocus = this.uiDialogButtonPane.find(":tabbable");
    }
    if (!hasFocus.length) {
        hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
    }
    if (!hasFocus.length) {
        hasFocus = this.uiDialog;
    }
    hasFocus.eq(0).focus();
},

_keepFocus: function (event) {
    function checkFocus() {
        var activeElement = this.document[0].activeElement,
            isActive = this.uiDialog[0] === activeElement ||
                $.contains(this.uiDialog[0], activeElement);
        if (!isActive) {
            this._focusTabbable();
        }
    }
    event.preventDefault();
    checkFocus.call(this);
    // support: IE
    // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
    // so we check again later
    this._delay(checkFocus);
},

取自此处:http://code.jquery.com/ui/1.10.1/jquery-ui.js

5 个答案:

答案 0 :(得分:8)

我发现的第二个答案是,在下面的代码中,jQuery将文档绑定到对话框。因此,当我点击所需按钮的onclick事件(或您正在处理的任何事件)时解除绑定:

 if (window.jQuery && window.jQuery.ui.dialog) {
   $(document).unbind("focusin.dialog");
 }

这是jQuery UI将_focusTabble()方法绑定到focusin.dialog文档事件的地方。

if ( !$.ui.dialog.overlayInstances ) {
            // Prevent use of anchors and inputs.
            // We use a delay in case the overlay is created from an
            // event that we're going to be cancelling. (#2804)
            this._delay(function() {
                // Handle .dialog().dialog("close") (#4065)
                if ( $.ui.dialog.overlayInstances ) {
                    this.document.bind( "focusin.dialog", function( event ) {
                        if ( !$( event.target ).closest(".ui-dialog").length &&
                                // TODO: Remove hack when datepicker implements
                                // the .ui-front logic (#8989)
                                !$( event.target ).closest(".ui-datepicker").length ) {
                            event.preventDefault();
                            $(".ui-dialog:visible:last .ui-dialog-content")
                                .data("ui-dialog")._focusTabbable();
                        }
                    });
                }
            });
        }

答案 1 :(得分:1)

我为解决此问题所做的是评论此$(".ui-dialog:visible:last .ui-dialog-content").data("ui-dialog")._focusTabbable();

您可以在下面找到完整的代码:

    if ( !$.ui.dialog.overlayInstances ) {
        // Prevent use of anchors and inputs.
        // We use a delay in case the overlay is created from an
        // event that we're going to be cancelling. (#2804)
        this._delay(function() {
            // Handle .dialog().dialog("close") (#4065)
            if ( $.ui.dialog.overlayInstances ) {
                this.document.bind( "focusin.dialog", function( event ) {
                    if ( !$( event.target ).closest(".ui-dialog").length &&
                            // TODO: Remove hack when datepicker implements
                            // the .ui-front logic (#8989)
                            !$( event.target ).closest(".ui-datepicker").length ) {
                        event.preventDefault();
                        //$(".ui-dialog:visible:last .ui-dialog-content")
                            //.data("ui-dialog")._focusTabbable();
                    }
                });
            }
        });
    }

答案 2 :(得分:0)

我有一个类似的问题,我需要把焦点放在我的对话框(WCAG)的内容中。单独使用focus()失败了,所以我添加的对话框实例中的最终解决方案是什么:

focus: function(event, ui) {
                    setTimeout(function(){ 
                        $('#element').blur().focus().css({'color': '#000', 'text-decoration' : 'none', 'cursor' : 'default'});
                    }, 500);
                }

我使用超时来确保兼容性。 *注意,我制作了##;#element&#39;一个锚标签(交互元素),所以焦点将采取。这就是造型的原因。

此代码应该能够添加到&#34; open&#34; jQuery对话框的功能。

答案 3 :(得分:0)

从jquery对话框停止阻止焦点的另一种方法

$.widget("ui.dialog", $.ui.dialog, {
    _allowInteraction: function (event) {
        return !!$(event.target).closest(".input-container").length || this._super(event);
    }
});

.input-container所在的容器包含应获得焦点的控件。

答案 4 :(得分:0)

那是因为jquery阻止了对话框子对象之外的焦点,所以jquery具有您可以阅读的该方法,该方法会将要允许焦点的其他元素列入白名单。

“ _ allowInteraction(event)返回:布尔型模态对话框不允许 用户与对话框后面的元素进行交互。这可以是 对于不是对话框的子元素但是 绝对看起来像它们。的 _allowInteraction()方法确定是否应允许用户与给定的目标元素进行交互;因此,它可以是 用于将不是对话框子元素的白名单列入白名单,但是您 希望用户能够使用。”

https://api.jqueryui.com/dialog/#method-_allowInteraction

所以我要对类 .other-popups 的某些项目禁用此“块焦点”,是在代码中添加此行

$.widget( "ui.dialog", $.ui.dialog, {
    _allowInteraction: function( event ) {
        return !!$( event.target ).closest( ".other-popups" ).length || this._super( event );
    }
});

或者完全禁用

 $.widget( "ui.dialog", $.ui.dialog, {
        _allowInteraction: function( event ) {
            return true ;
        }
    });