如何使用jQuery关闭对话框?

23

我正在使用以下代码动态创建jQuery UI Dialog小部件:

 $(function () {
        var Selector = $("a:contains('sometext')");
        $(Selector).bind('click', function () {
            var NewDialog = "<div dir=rtl id='MenuDialog'></div>";
            var DialogContetn = '<div dir=rtl ><table width=100%><tr><td><textarea id="txtRequestContent" cols="30" rows="2"></textarea></td><td><table><tr><td><input id="btnSendEditionRequest" type="button" value="Send" /></td></tr><tr><td><input id="btnCloseDialog" type="button" value="Cancel" /></td></tr></table></td></tr></table></div>';
            $('body').append(NewDialog);
            $('#MenuDialog').html(DialogContetn);
            $('#MenuDialog').hide();
            $('#MenuDialog').dialog({ modal: true, title: "title", show: 'clip', hide: 'clip' });
            $("#btnCloseDialog").live('click', function () {
                $("#MenuDialog").dialog('close');
            });
            return false;
        });
    });

第一次加载时,jQuery对话框正常工作,当我点击btnCloseDialog时,jQuery对话框可以成功关闭。

但是,在此之后,btnCloseDialog不再关闭对话框。为什么会发生这种情况?

更新:

我将我的代码放在 jsfiddle 上。

这是奇怪的行为,因为该按钮可以在jsFiddle上正确关闭对话框,但在我的项目中则不行。


1
只是出于好奇,为什么你使用selector.bind而不是selector.click? - eugeneK
好问题。 只是习惯问题。 它会影响性能吗? - Shahin
1
我不确定,但我猜测bind循环遍历提供的项目事件集合,然后应用与click相同的函数。所以我敢打赌它会影响性能,但这是我编写此模块的方式。John Resig和其他jQuery团队成员可能有更好的想法。 - eugeneK
我检查了: $('#test').click(function() { //无论如何... }); 是下面代码的别名。 $('#test').bind('click', function() { //无论如何... }); - Shahin
5个回答

42

因为这篇文章在搜索动态对话框的jQuery相关问题时很容易出现,我想指出更好的实现方法。不要先将您的对话框div和内容添加到HTML中再调用它,而是可以通过将HTML直接塞入jQuery对象来更轻松地完成,如下所示:

$(function () {
    $("a:contains('sometext')").click(function() {
        var NewDialog = $('<div id="MenuDialog">\
            <p>This is your dialog content, which can be multiline and dynamic.</p>\
        </div>');
        NewDialog.dialog({
            modal: true,
            title: "title",
            show: 'clip',
            hide: 'clip',
            buttons: [
                {text: "Submit", click: function() {doSomething()}},
                {text: "Cancel", click: function() {$(this).dialog("close")}}
            ]
        });
        return false;
    });
});

我还展示了如何使用内联函数放置多个按钮,而不是将live()函数附加到按钮上。 我在几个地方都使用了这种方法,对我来说效果很好。它还支持表单(我在doSomething()函数中获取了数据并通过ajax提交,但其他方法也可以),等等。


8
我尝试使用这段代码,大部分都是原样的,但FireBug在DOM中显示对话框堆叠在body标签的末尾(每次我点击打开对话框时都会出现)。我认为对于这种类型的动态对话框,您可能希望使用destroy而不是close -- $(this).dialog("destroy")。 - eselk

3

在动态创建的内容中,您最好不要使用id,因为您可能会得到具有相同id的多个元素 - 这意味着document.getElementById(我假设sizzle用于#id选择器)只会返回第一个(潜在的不可见)元素。


这样怎么样: 如果 (Selector.lenght) { //创建动态内容 } - Shahin

2
我需要一种方法来使用JSON webservice来控制客户端的警报和更新等操作,而无需客户端发起动作。我希望将其更新为使用WebSockets,但目前它是一个定时拉取,每次拉取都包括下一次拉取的延迟,因此一旦客户端加载了我的系统,我甚至可以管理它。
我还使用show/expire和moment.js按日期时间过滤,然后使用每个警报的ID(未在此处显示)与cookie配合使用以防止重复通知。这正在顺利进行中,如果有足够的兴趣,我可能很快就会决定将其打包成库。
关于这个问题的特定部分有两个部分。1)包括jQuery.dialog()参数的JSON和2)使用该JSON创建对话框的代码。关键在于注意我如何引用“n”对象参数并使用它们动态地创建对话框。tDlg对象是其中的一个重要部分,因为它最终代表对话框,并传递到$().dialog()中。
JSON片段包括我的对话框参数:
"doAlert":{
                "modal":false
                ,"height":240
                ,"width":380
                ,"title":"Welcome to the new BatchManager"
                ,"body":"<div style='text-align:center;'>Welcome to the new and enhanced<br/>BatchManager!</div><div style='text-align:center;'>Enjoy!</div>"
                ,"buttons":[
                    {
                        "text":"Ok"
                        ,"click":"$(this).dialog('close');"
                    }
                ]
            }

以下是使用jQuery的JavaScript代码片段,可以根据我的JSON数据进行对话框初始化(n对应于doAlert,在此示例中它是“notices”数组的一部分):

var tDlg = {
    resizable: false,
    height: (n.doAlert.height) ? n.doAlert.height : 240,
    width: (n.doAlert.width) ? n.doAlert.width : 240,
    modal: (n.doAlert.modal) ? n.doAlert.modal : true,
    dialogClass: "dlgFont"
};
if (n.doAlert.buttons) {
    tDlg.buttons = [];
    $.each(n.doAlert.buttons, function (i, n) {
            tDlg.buttons.push({
                            text: n.text,
                            click: new Function(n.click)
                    })
    })
}
$('<div class="dlgFont" title="' + n.doAlert.title + '"><p><span class="ui-icon ui-icon-circle-check" style="float: left; margin: 0 7px 50px 0;"></span>' + n.doAlert.body + '</div>').dialog(tDlg);

1
个人而言,我是这样处理的:
1)构建对话框的HTML,其中包含两个默认值为xxx的span。
<div id="dialog1" title="Title of the dialog">
    <p>There are two variables: <span id="var1">xxx</span> and
    <span id="var2">xxx</span></p>
</div>

2) 将 div 准备好作为对话框

$(function() {
    $( "#dialog1").dialog({
    autoOpen:false,
        modal: true,
        buttons: {
        "Button 1": function() {
            $(this).dialog( "close" );
        },
        "Button 2": function() {
            $(this).dialog( "close" );
        }
    }
    });
});

3) 在启动对话框之前,使用此函数修改这两个跨度的值:

function showDialog(value1,value2){
    $("#var1").html(value1);
    $("#var2").html(value2);
    $( "#dialog1").dialog('open');
} 

4) 当您需要时,以这种方式调用函数

showDialog('tom','jerry'); 

您可以在http://jsfiddle.net/sekmo/L46vb/1/尝试此操作。


1

需要考虑的几个要点:

  1. OnDialogClose 你应该将 #MenuDialog 从 DOM 中分离,以避免具有相同 ID 的多个对象,或者在添加之前可以检查是否存在 div#MenuDialog

  2. var Selector = $("a:contains('sometext')"); 是无意义的代码行,除非你在其他地方重复使用它。

  3. 你多次使用了 $('#MenuDialog')。最好将其分配给一个变量,而不是一遍又一遍地查询 var Selector = $('#MenuDialog');


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接