1

我有一个模态窗口脚本,我们正在努力提高可访问性要求的速度。该要求说,当您离开窗口时,它应该关闭。它还说,在关闭窗口时,原始触发元素必须重新获得焦点。

在做了一些挖掘之后,我发现了这个:jQuery figuring if parent has lost 'focus'。似乎判断您何时离开窗口的最简单方法是跟踪 focusin 事件,当焦点在不是打开模式的子元素上触发时,关闭窗口。然而,这种方法是有问题的,正如您将看到的(更不用说对我来说有点太重了)。这是处理此问题的代码:

$('body').focusin(function(e) {
        if (!$(e.target).parent().is('.current-window')) {
            closeModal();
        }
    });

以及关闭窗口的功能:

function closeModal() {
        $('.modal-mask, .current-window').fadeOut('fast', function(){
            $(this).removeClass('current-window');
            $('.modal-mask').removeAttr('style');
            $('.modal-trigger').focus();
        });
    }

现在很明显,当我运行此代码时,closeModal() 在 focusin 事件与最大调用堆栈之间来回触发,因此在将焦点赋予触发元素之前抛出“超出最大调用堆栈”错误消息。

有关完整代码,请参阅此小提琴:http: //jsfiddle.net/pbredenberg/wxX4T/

我试图想出一种更好的方法来处理这个要求,或者至少避免无限循环。谁能指出我正确的方向?

4

2 回答 2

0

我仍然无法发表评论,所以我必须提交这个作为答案:你为什么不跟踪你是否真的用像 window.closure 的 bool var 关闭窗口?我更新了示例: http: //jsfiddle.net/kevkong/wxX4T/8/ 这是你打算做什么?

于 2012-10-10T15:19:03.833 回答
0

每当您打开模态框时,存储对被单击元素的引用。然后,当模式关闭时,您可以检索它并重新聚焦元素。

工作演示:http: //jsfiddle.net/wxX4T/12/

function closeModal(e) {
    if (e) e.preventDefault();

    // Rather than using a .current-window class
    // we can use the jQuery :visible pseudo-selector
    var $window = $(".window:visible");

    // Get our refernce to the focus target that was 
    // stored when the window was open.
    var $trigger = $window.data("focusTarget");

    // Close the window and mask
    $('.modal-mask, .window').fadeOut('fast', function() {
        // Focus on the original trigger
        $trigger.focus();
    });
}

$('.modal').click(function(e) {
    e.preventDefault();

    var $trigger = $(this);
    var $modal = $($trigger.attr("href")).fadeIn(300)
    $('.modal-mask').fadeIn(200);

    // I have omitted all the code that positions
    // the window (for the sake of clarity)
    // Feel free to add it back.
    // Store a reference to the trigger link in the modal's "data" hash 
    // so that when we close it later, we can retrieve the original 
    // trigger that opened the window.
    $modal.data("focusTarget", $trigger);
});


// Trigger window close based on Tab key
$(document).on("keydown", function(e) {
    // Only close modal if the tab key is pressed
    // AND if there is a visible modal window.
    if ((e.keyCode || e.which) === 9 && $(".window:visible").length > 0) {
        e.preventDefault();
        closeModal();
    }
});

$(document).on("click", ".window .close", closeModal);

$(document).on("click", ".modal-mask", function() {
    $(this).hide();
    closeModal();
});​
于 2012-10-10T16:08:25.127 回答