2012-10-10 57 views
1

我有,我們正試圖把加快速度進行無障礙的要求模態窗口腳本。要求說,當你離開窗戶時,它應該關閉。它還表示,在解散窗戶後,原始觸發元素必須重新獲得焦點。jQuery的:當焦點離開元素的兒童檢測,然後將焦點回到觸發元件

做了一些挖掘後,我發現這個:jQuery figuring out 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/

我試圖想到一個更好的方式來處理這個要求,或者至少是避免無限循環。任何人都可以將我指向正確的方向嗎?

+0

所以'$( '模式觸發')專注()'創建的模式? –

+0

不,如果您檢查我發佈的小提琴,您會看到窗口的創建位置。 '$('。modal-trigger')。focus()'在窗口關閉後將焦點返回到觸發元素。 – paulwhitman

回答

0

我仍然無法發表評論,所以我必須提交此作爲答案: 爲什麼不跟蹤,如果你實際上是關閉與window.closing布爾變量的窗口? 我更新了例子:http://jsfiddle.net/kevkong/wxX4T/8/ 這是,你打算做什麼?

+0

這工作出色,謝謝! – paulwhitman

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

非常簡單明智的解決方案謝謝! – paulwhitman