4

TL;DR;

を強制的にfocusWeb ページのモーダル ボックス内に配置する方法はありますか?

ここに問題があります。テキスト、リンク、およびフォームを含む従来の Web ページがあります。ページ内の特定のリンクをクリックすると、モーダル ボックスが表示されます (fancyboxまたはのようなものjQuery.ui.dialog)。このモーダルには、リンクとフォーム要素も含まれています。ユーザーがその"tab"キーを使用すると、モーダルの内側にある要素だけでなく、モーダルの外側にある要素も含め、ページ上のすべての要素にフォーカスできます。モーダルボックス内で強制的にフォーカスしたいのですが、それを行う方法が見つかりません。可能であれば、CSS または JavaScript でこれを行いたいと考えています。

jQuery.ui.dialogオプションを使用して実行できるため、これが可能であることはわかっています。 http://jsfiddle.net/pomeh/QjLJk/1/show/modalの例を次に示します。ソースコードを見ようとしましたが、正確にどのように機能するかわかりません。この問題を解決するように聞こえるjQuery UIソースコードで見つけたコードを次に示します。

this.document.bind( "focusin.dialog", function( event ) {
    if ( !that._allowInteraction( event ) ) {
        event.preventDefault();
        $(".ui-dialog:visible:last .ui-dialog-content")
            .data( widgetFullName )._focusTabbable();
    }
});

_allowInteraction: function( event ) {
    if ( $( event.target ).closest(".ui-dialog").length ) {
        return true;
    }

    // TODO: Remove hack when datepicker implements
    // the .ui-front logic (#8989)
    return !!$( event.target ).closest(".ui-datepicker").length;
},

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


keydown: function( event ) {
    if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
            event.keyCode === $.ui.keyCode.ESCAPE ) {
        event.preventDefault();
        this.close( event );
        return;
    }

    // prevent tabbing out of dialogs
    if ( event.keyCode !== $.ui.keyCode.TAB ) {
        return;
    }
    var tabbables = this.uiDialog.find(":tabbable"),
        first = tabbables.filter(":first"),
        last  = tabbables.filter(":last");

    if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
        first.focus( 1 );
        event.preventDefault();
    } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
        last.focus( 1 );
        event.preventDefault();
    }
}
4

1 に答える 1

1

コードはすでにあるので、コーディングには触れません。その背後にあるロジックについて説明します。

ページに次の要素がある場合、

要素0(タブインデックス1) --> 要素1(タブインデックス2) --> 要素2(タブインデックス3)

フォーカスが外れないように、基本的にはサイクルを作成します。

element0 でタブ キーを押すと、通常どおり element1 に移動します。

しかし、要素 2 でタブ キーが押された場合、(event.preventDefault() によって) ブラウザーの既定の動作を防止する必要があります。つまり、より高い tabindex を持つ要素に移動し、要素 0 にフォーカスを移します。

element0 で Shift+ タブが押されたときと同じように、ブラウザーのデフォルトの動作 (event.preventDefault()) を防止し、手動で element2 にフォーカスを与える必要があります。

このようにして、フォーカスが外に出ないようにサイクルを作成します。

于 2013-05-29T16:55:21.173 に答える