我有一个模态窗口脚本,我们正在努力提高可访问性要求。要求说当你离开窗户时,它应该关闭。它还说,在解除窗口时,原始触发元素必须重新聚焦。
在做了一些挖掘后,我发现了这个:jQuery figuring out if parent has lost 'focus'。当你从窗口中跳出标签时,最简单的方法就是跟踪focusin事件,当焦点触发一个不是open模式子元素的元素时,关闭窗口。然而,这种方法是有问题的,因为你会看到(更不用说我的喜欢有点太重了)。以下是处理此问题的代码:
$('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事件之间来回触发直到最大调用堆栈,因此在将焦点提供给触发元素之前会抛出“超出最大调用堆栈”错误消息。 / p>
有关完整代码,请参阅此小提琴:http://jsfiddle.net/pbredenberg/wxX4T/
我正在尝试考虑一种更好的方法来处理这个要求,或者至少避免无限循环。有人能指出我正确的方向吗?
答案 0 :(得分:0)
我仍然无法发表评论,因此我必须将此作为答案提交: 为什么不跟踪你是否真的关闭了像window.closing这样的bool var的窗口? 我更新了示例:http://jsfiddle.net/kevkong/wxX4T/8/ 这是你打算做什么的吗?
答案 1 :(得分: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();
});