Как вы проверяете, что модальный диалог jquery потерял фокус? - PullRequest
1 голос
/ 25 мая 2009

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

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


РЕДАКТИРОВАТЬ У меня тоже есть этот вопрос, но я не могу обойтись ни одним из предоставленных в настоящее время ответов, так как я не могу сделать свои диалоговые окна модальными.

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

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

Ответы [ 8 ]

10 голосов
/ 13 мая 2011

Чистый 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');

    }
})
5 голосов
/ 25 мая 2009

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

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

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

1 голос
/ 13 мая 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/

1 голос
/ 11 мая 2011

Посмотрите на jquery tools overlay , который может помочь вам сделать модальные окна. Это помогло мне в прошлом.

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

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
});
1 голос
/ 30 мая 2009

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

$('.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 может показаться пользователю «вне» группы элементов, хотя на самом деле он является дочерним элементом одного из этих элементов. Это не совсем подходит для этого, но должно работать для ваших целей.

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

0 голосов
/ 13 мая 2011

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

0 голосов
/ 25 мая 2009

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

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

0 голосов
/ 25 мая 2009

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

$("element").blur(function(){
  /* Callback goes here */
  $("element").hide();
}); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...