У меня есть диалоговое окно jQuery UI, которое отображается при нажатии на отдельные элементы. Я хотел бы закрыть диалоговое окно, если щелчок происходит где угодно, кроме тех элементов запуска или самого диалога.
Вот код для открытия диалога:
$(document).ready(function() {
var $field_hint = $('<div></div>')
.dialog({
autoOpen: false,
minHeight: 50,
resizable: false,
width: 375
});
$('.hint').click(function() {
var $hint = $(this);
$field_hint.html($hint.html());
$field_hint.dialog('option', 'position', [162, $hint.offset().top + 25]);
$field_hint.dialog('option', 'title', $hint.siblings('label').html());
$field_hint.dialog('open');
});
/*$(document).click(function() {
$field_hint.dialog('close');
});*/
});
Если я раскомментирую последнюю часть, диалог никогда не открывается. Я предполагаю, что тот же самый щелчок, который открывает диалог, снова закрывает его.
Окончательный рабочий код
Примечание: используется jQuery вне событий плагин
$(document).ready(function() {
// dialog element to .hint
var $field_hint = $('<div></div>')
.dialog({
autoOpen: false,
minHeight: 0,
resizable: false,
width: 376
})
.bind('clickoutside', function(e) {
$target = $(e.target);
if (!$target.filter('.hint').length
&& !$target.filter('.hintclickicon').length) {
$field_hint.dialog('close');
}
});
// attach dialog element to .hint elements
$('.hint').click(function() {
var $hint = $(this);
$field_hint.html('<div style="max-height: 300px;">' + $hint.html() + '</div>');
$field_hint.dialog('option', 'position', [$hint.offset().left - 384, $hint.offset().top + 24 - $(document).scrollTop()]);
$field_hint.dialog('option', 'title', $hint.siblings('label').html());
$field_hint.dialog('open');
});
// trigger .hint dialog with an anchor tag referencing the form element
$('.hintclickicon').click(function(e) {
e.preventDefault();
$($(this).get(0).hash + ' .hint').trigger('click');
});
});
Откроется плагин jQuery Outside Events
Позволяет выполнить следующие действия:
$field_hint.bind('clickoutside',function(){
$field_hint.dialog('close');
});
Извините, что перетащил его так долго, но я использовал ниже. Любые недостатки? См. Открытую функцию...
$("#popup").dialog(
{
height: 670,
width: 680,
modal: true,
autoOpen: false,
close: function(event, ui) { $('#wrap').show(); },
open: function(event, ui)
{
$('.ui-widget-overlay').bind('click', function()
{
$("#popup").dialog('close');
});
}
});
$('.ui-widget-overlay').bind('click', function () { $(this).siblings('.ui-dialog').find('.ui-dialog-content').dialog('close'); });
ссылку на идентификатор: $('.ui-widget-overlay').bind('click', function () { $(this).siblings('.ui-dialog').find('.ui-dialog-content').dialog('close'); });
Забудьте использовать другой плагин:
Ниже приведены 3 метода закрытия диалогового окна пользовательского интерфейса jquery при нажатии за пределами popin:
Если диалог является модальным/имеет фоновое наложение: http://jsfiddle.net/jasonday/6FGqN/
jQuery(document).ready(function() {
jQuery("#dialog").dialog({
bgiframe: true,
autoOpen: false,
height: 100,
modal: true,
open: function(){
jQuery('.ui-widget-overlay').bind('click',function(){
jQuery('#dialog').dialog('close');
})
}
});
});
Если диалог немодальный Метод 1: метод 1: http://jsfiddle.net/jasonday/xpkFf/
// Close Pop-in If the user clicks anywhere else on the page
jQuery('body')
.bind(
'click',
function(e){
if(
jQuery('#dialog').dialog('isOpen')
&& !jQuery(e.target).is('.ui-dialog, a')
&& !jQuery(e.target).closest('.ui-dialog').length
){
jQuery('#dialog').dialog('close');
}
}
);
Немодальное диалоговое окно Метод 2: http://jsfiddle.net/jasonday/eccKr/
$(function() {
$( "#dialog" ).dialog({
autoOpen: false,
minHeight: 100,
width: 342,
draggable: true,
resizable: false,
modal: false,
closeText: 'Close',
open: function() {
closedialog = 1;
$(document).bind('click', overlayclickclose);
},
focus: function() {
closedialog = 0;
},
close: function() {
$(document).unbind('click');
}
});
$('#linkID').click(function() {
$('#dialog').dialog('open');
closedialog = 0;
});
var closedialog;
function overlayclickclose() {
if (closedialog) {
$('#dialog').dialog('close');
}
//set to one because click on dialog box sets to zero
closedialog = 1;
}
});
Просто добавьте этот глобальный script, который закрывает все модальные диалоги, просто нажимая на них.
$(document).ready(function()
{
$(document.body).on("click", ".ui-widget-overlay", function()
{
$.each($(".ui-dialog"), function()
{
var $dialog;
$dialog = $(this).children(".ui-dialog-content");
if($dialog.dialog("option", "modal"))
{
$dialog.dialog("close");
}
});
});;
});
$(".ui-widget-overlay").click (function () {
$("#dialog-id").dialog( "close" );
});
Fiddle, показывая приведенный выше код в действии.
Мне пришлось сделать две части. Сначала внешний обработчик кликов:
$(document).on('click', function(e){
if ($(".ui-dialog").length) {
if (!$(e.target).parents().filter('.ui-dialog').length) {
$('.ui-dialog-content').dialog('close');
}
}
});
Это вызывает dialog('close')
в общем классе ui-dialog-content
, и поэтому закроет диалоговые окна all, если щелчок не возник из одного. Он также будет работать с модальными диалогами, поскольку наложение не является частью поля .ui-dialog
.
Проблема заключается в следующем:
Чтобы исправить это, мне пришлось добавить stopPropagation для этих обработчиков кликов:
moreLink.on('click', function (e) {
listBox.dialog();
e.stopPropagation(); //Don't trigger the outside click handler
});
$('body').on('click', '.ui-widget-overlay', function () { $('#myDialog').dialog('close'); });
Вы можете сделать это без использования дополнительного плагина
var $dialog= $(document.createElement("div")).appendTo(document.body);
var dialogOverlay;
$dialog.dialog({
title: "Your title",
modal: true,
resizable: true,
draggable: false,
autoOpen: false,
width: "auto",
show: "fade",
hide: "fade",
open:function(){
$dialog.dialog('widget').animate({
width: "+=300",
left: "-=150"
});
//get the last overlay in the dom
$dialogOverlay = $(".ui-widget-overlay").last();
//remove any event handler bound to it.
$dialogOverlay.unbind();
$dialogOverlay.click(function(){
//close the dialog whenever the overlay is clicked.
$dialog.dialog("close");
});
}
});
Здесь $dialog - диалог. В основном мы делаем, чтобы получить последний оверлейный виджет при открытии этого диалога и привязать обработчик кликов к этому наложению, чтобы закрыть диалоговое окно $, как и при нажатии на оверлей.
Этот вопрос немного стар, но если кто-то хочет закрыть диалоговое окно, которое НЕ является модальным, когда пользователь нажимает где-нибудь, вы можете использовать это, которое я взял из Плагин JQuery UI Multiselect. Главное преимущество заключается в том, что щелчок не "потерян" (если пользователь хочет нажать ссылку или кнопку, действие будет выполнено).
$myselector.dialog({
title: "Dialog that closes when user clicks outside",
modal:false,
close: function(){
$(document).off('mousedown.mydialog');
},
open: function(event, ui) {
var $dialog = $(this).dialog('widget');
$(document).on('mousedown.mydialog', function(e) {
// Close when user clicks elsewhere
if($dialog.dialog('isOpen') && !$.contains($myselector.dialog('widget')[0], e.target)){
$myselector.dialog('close');
}
});
}
});
var $dialog = $(this).dialog('widget');
внутри обработчика события по нажатию
нет необходимости в плагине внешних событий...
просто добавьте обработчик событий в .ui-widget-overlay div:
jQuery(document).on('click', 'body > .ui-widget-overlay', function(){
jQuery("#ui-dialog-selector-goes-here").dialog("close");
return false;
});
просто убедитесь, что любой селектор, который вы использовали для диалога jQuery ui, также вызывается, чтобы закрыть его. Т.е. # ui-dialog-selector-go-here
Это не использует jQuery UI, но использует jQuery и может быть полезным для тех, кто не использует jQuery UI по любой причине. Сделайте это так:
function showDialog(){
$('#dialog').show();
$('*').on('click',function(e){
$('#zoomer').hide();
});
}
$(document).ready(function(){
showDialog();
});
Итак, как только я показал диалог, я добавляю обработчик кликов, который ищет только первый щелчок по чему-либо.
Теперь было бы лучше, если бы я мог заставить его игнорировать клики по чему-либо на #dialog и его содержимом, но когда я попытался переключить $('*') на $(': not ( "# dialog, # dialog *" ) '), он все еще обнаружил #dialog-клики.
В любом случае, я использовал это только для фото лайтбокса, так что с этой целью он работал нормально.
Данный пример использует один диалог с id '#dialog', мне нужно решение, которое закрывает любое диалоговое окно:
$.extend($.ui.dialog.prototype.options, {
modal: true,
open: function(object) {
jQuery('.ui-widget-overlay').bind('click', function() {
var id = jQuery(object.target).attr('id');
jQuery('#'+id).dialog('close');
})
}
});
Спасибо моему коллеге вашему Arkesteijn за предложение использовать прототип.
Это единственный метод, который работал у меня для моего диалогового окна NON-MODAL
$(document).mousedown(function(e) {
var clicked = $(e.target); // get the element clicked
if (clicked.is('#dlg') || clicked.parents().is('#dlg') || clicked.is('.ui-dialog-titlebar')) {
return; // click happened within the dialog, do nothing here
} else { // click was outside the dialog, so close it
$('#dlg').dialog("close");
}
});
Весь кредит принадлежит Axle
Нажмите внешнее немодальное диалоговое окно, чтобы закрыть
У меня была такая же проблема, пока вы просматривали модальный текст на одной странице. После многих поисковых запросов я нашел это очень полезное решение. С событием и целью он проверяет, где произошло щелчок, и в зависимости от него срабатывает действие или ничего не делает.
Сайт библиотеки фрагментов кода
$('#modal-background').mousedown(function(e) {
var clicked = $(e.target);
if (clicked.is('#modal-content') || clicked.parents().is('#modal-content'))
return;
} else {
$('#modal-background').hide();
}
});
Я использую это решение на основе одного опубликованного здесь:
var g_divOpenDialog = null;
function _openDlg(l_d) {
// http://stackoverflow.com/questions/2554779/jquery-ui-close-dialog-when-clicked-outside
jQuery('body').bind(
'click',
function(e){
if(
g_divOpenDialog!=null
&& !jQuery(e.target).is('.ui-dialog, a')
&& !jQuery(e.target).closest('.ui-dialog').length
){
_closeDlg();
}
}
);
setTimeout(function() {
g_divOpenDialog = l_d;
g_divOpenDialog.dialog();
}, 500);
}
function _closeDlg() {
jQuery('body').unbind('click');
g_divOpenDialog.dialog('close');
g_divOpenDialog.dialog('destroy');
g_divOpenDialog = null;
}
Для тех, кого вас интересует, я создал общий плагин, который позволяет закрыть диалог при нажатии вне его, будь то модальный или немодальный диалог. Он поддерживает один или несколько диалогов на одной странице.
Дополнительная информация здесь: http://www.coheractio.com/blog/closing-jquery-ui-dialog-widget-when-clicking-outside
Лоран
С помощью следующего кода вы можете имитировать щелчок по кнопке "закрыть" в диалоговом окне (измените строку "MY_DIALOG" для имени вашего собственного диалога)
$("div[aria-labelledby='ui-dialog-title-MY_DIALOG'] div.ui-helper-clearfix a.ui-dialog-titlebar-close")[0].click();
Я не думаю, что поиск диалога с использованием $('. any-selector') из всего DOM настолько яркий.
Try
$('<div />').dialog({
open: function(event, ui){
var ins = $(this).dialog('instance');
var overlay = ins.overlay;
overlay.off('click').on('click', {$dialog: $(this)}, function(event){
event.data.$dialog.dialog('close');
});
}
});
Вы действительно получаете оверлей из экземпляра диалогового окна, к которому он принадлежит, поэтому все будет не так.
Это просто на самом деле вам не нужны никакие плагины, просто jquery или вы можете сделать это с помощью простого javascript.
$('#dialog').on('click', function(e){
e.stopPropagation();
});
$(document.body).on('click', function(e){
master.hide();
});