Как вы проверяете, что модальное диалоговое окно jquery потеряло фокус?

Я хочу закрыть диалоговое окно, когда вы щелкаете за пределами диалогового окна, но я не уверен, как вы проверяете это в jquery/plain javascript.

Некоторые предлагали использовать событие размытия, но, похоже, это не поддерживается диалоговым окном jquery.


EDIT У меня тоже есть этот вопрос, но я не могу обойтись ни одним из имеющихся ответов, так как я не могу сделать свои диалоговые окна модальными.

Мне это нужно, чтобы я мог регистрировать обработчики клавиш только тогда, когда диалоговое окно является самым верхним, и отменять их регистрацию, как только другое диалоговое окно появляется наверху.

Есть ли у кого-нибудь решение - в идеале такое, которое приводит к возникновению события каждый раз, когда какой-либо другой диалог появляется наверху?


person zlog    schedule 25.05.2009    source источник


Ответы (8)


Можете ли вы сделать свой диалог модальным? Если это так, то вы можете (вероятно) добиться того, что вам нужно, с помощью событий в модальном наложении...

Совершенно хакерская, непроверенная идея, но она может просто сработать...

Модальные диалоги создают события, называемые click.dialog-overlay и т. д. Они запускаются, когда щелкают мышью за пределами диалога, на модальном наложении. Перехват этих событий и закрытие диалогового окна может просто сделать то, что вы пытаетесь сделать...

person Stobor    schedule 25.05.2009
comment
Это работает. Диалоговое окно JQuery, кажется, добавляет класс ui-widget-overlay при создании диалогового окна, поэтому я сделал что-то вроде: $('.ui-widget-overlay').click(function() { $(#dialog).dialog( близко); }); - person zlog; 20.08.2009

Чистый jQueryUI без модального диалога.

Пример:

http://jsfiddle.net/marcosfromero/x4GXy/

Код:

// Bind the click event to window
$(window).click(function(event) {
    if (($(event.target).closest('.ui-dialog')).length>0) {
        // if clicked on a dialog, do nothing
        return false;
    } else {
        // if clicked outside the dialog, close it
        // jQuery-UI dialog adds ui-dialog-content class to the dialog element.
        // with the following selector, we are sure that any visible dialog is closed.
        $('.ui-dialog-content:visible').dialog('close');

    }
})
person marcosfromero    schedule 13.05.2011

Событие размытия - это не совсем то, что вы ищете. Событие размытия происходит на одном элементе. То, что вы ищете, — это когда пользователь щелкает «вне» определенной группы элементов — все, что находится ниже определенного родительского узла. ** Для этого нет события, поэтому вам нужно имитировать его с помощью событий, к которым у вас есть доступ. .

$('.dialogSelector').dialog({
  open: function(e) { // on the open event
    // find the dialog element
    var dialogEl = $(this).parents('.ui-dialog')[0];        
    $(document).click(function (e) { // when anywhere in the doc is clicked
        var clickedOutside = true; // start searching assuming we clicked outside
        $(e.target).parents().andSelf().each(function () { // search parents and self
            // if the original dialog selector is the click's target or a parent of the target
            // we have not clicked outside the box
            if (this == dialogEl) {
                clickedOutside = false; // found
                return false; // stop searching
            }
        });
        if (clickedOutside) {
            $('a.ui-dialog-titlebar-close').click(); // close the dialog
            // unbind this listener, we're done with it
            $(document).unbind('click',arguments.callee); 
        }
    });     
  }
});

** Чтобы быть более точным, вы ищете событие, когда пользователь щелкает за пределами определенной видимой группы элементов. Абсолютно позиционированный элемент div может казаться пользователю «вне» группы элементов, хотя на самом деле он является дочерним элементом одного из этих элементов. Это не совсем сработает для этого, но должно сработать для ваших целей.

Надеюсь, это поможет. :)

person Keith Bentrup    schedule 30.05.2009

Взгляните на наложение инструментов jquery, которое может помочь вам в создании модальных окон. Это помогло мне в прошлом.

Чтобы проверить, находится ли щелчок за пределами модального окна, вы можете сделать что-то вроде этого:

echo '<div class="mybody">Body of the webpage';
echo '<div class="myoverlay">Body of overlay</div></div>';

JQuery:

$(function() {
    $('body').click(function(e) {
        var inOverlay = false;
        $(e.target).parents().each(function(idx,parent) {
            if ('mybody' == parent.className) {
                inOverlay=true;
            }
        });
        if (!inOverlay) {
            alert('outside');
        }
    });
});

Затем вы можете добавить проверки клавиатуры внутри модального окна:

$(".myoverlay").keydown(function(e) {
   // your specific keyboard handler
});
person Gevious    schedule 11.05.2011

Решение, похожее на @marcosfromero (но более эффективное), заключается в использовании $.contains для проверки существования элемента внутри другого. $.contains использует собственный метод document.documentElement.compareDocumentPosition, если он существует, то есть вам не нужно превращать event.target в объект jQuery, не нужно запрашивать DOM для .ui-dialog, а базовой логике даже не нужно проходить через DOM (в современных браузерах).

$(document).click(function(event) {
    if( !$.contains( dialog.dialog('widget')[0], event.target ) ){
        $(':ui-dialog').dialog('close');    
    }
});

Если целевой элемент не существует с разметкой диалога, созданной виджетом (полученной путем вызова метода диалога widget), то диалог закрывается.

Демонстрация: http://jsfiddle.net/ehynds/auKAu/

person ehynds    schedule 13.05.2011

Я думаю, что это может сделать это:

$("element").blur(function(){
  /* Callback goes here */
  $("element").hide();
}); 
person Mike Tunnicliffe    schedule 25.05.2009
comment
Но плагин UI/Dialog не поддерживает событие размытия, не так ли? docs.jquery.com/UI/API/1.7/Dialog#events - person Stobor; 25.05.2009
comment
Будет ли это работать и для div? например, // #divElement имеет класс ui-dialog-content $(#divElement).blur(function() { $(#divElement).dialog(close); }); Кажется, это не работает. Я что-то пропустил? - person zlog; 25.05.2009
comment
Кажется немного странным, что Dialog имеет обработчик событий focus(), но не blur(). Спасибо, что просветили меня. - person Mike Tunnicliffe; 25.05.2009

используйте функцию .blur()... это замечательно: D

http://docs.jquery.com/Events/blur

person Ryan Rohrer    schedule 25.05.2009
comment
Но плагин UI/Dialog не поддерживает событие размытия, не так ли? docs.jquery.com/UI/API/1.7/Dialog#events - person Stobor; 25.05.2009

Создайте прозрачное наложение с помощью CSS {position:fixed;height:100%;width:100%;background:transparent;z-index:100} и используйте $('.overlay').click(function() {$('ui-dialog').remove();}. Конечно, вам нужно будет создать <div class="overlay"></div> одновременно с созданием диалога. И диалогу потребуется более высокий z-индекс!

person thugsb    schedule 12.05.2011