jQuery UI Focus Stealing

拜拜、爱过 提交于 2019-12-18 04:43:15

问题


Whenever I type something in the following Insert Hyperlink text input, all the words are going to textarea behind it. OK and Cancel buttons are working fine but I cannot focus to text input.

We'are using jQuery UI 1.10.1. It was working nicely with previous version of jQuery which was 1.8.x.

I've checked code behind of jQuery and it has the following methods called when opening a Modal Dialog:

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

that is taken from here: http://code.jquery.com/ui/1.10.1/jquery-ui.js


回答1:


Second answer I've found is that in the following code jQuery binds document to dialog. So when I unbind this when I click on the desired button's onclick event (or whatever event you're handling):

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

This is where jQuery UI binds it _focusTabble() method to focusin.dialog event of document.

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:


What I did to solve this problem is to comment out this $(".ui-dialog:visible:last .ui-dialog-content").data("ui-dialog")._focusTabbable();

You can find the complete code below:

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



回答3:


I had a similar issue where I needed the focus to be within the content of my dialog box (for WCAG). Using focus() alone failed, so what my end solution was in the dialog instantiation I added:

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

I used the timeout to ensure compatibility. *Note, I made the '#element' an anchor tag (interactive element) so the focus would take. That is the reason for the styling.

This code should be able to be added into the "open" function of the jQuery Dialog as well.




回答4:


Another way to stop blocking focus from jquery dialog

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

Where .input-container is container which contains controls that should receive focus.



来源:https://stackoverflow.com/questions/15665552/jquery-ui-focus-stealing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!