简体   繁体   English

正确整理jQuery对话框

[英]Properly tidying up a jQuery Dialog

I hit a problem when using jQuery's Dialog widget... 我在使用jQuery的Dialog小部件时遇到问题...

I have a solution, but wondered if there was a more standard way (or I had mis-understood something): 我有一个解决方案,但想知道是否还有更标准的方法(或者我误解了一些东西):

Background 背景

I have a web site that makes heavy use of AJAX, in that most of the time only portions of the page are updated. 我有一个大量使用AJAX的网站,因为在大多数情况下,仅更新页面的一部分。 One portion of the page contains some JS that opens a dialog. 页面的一部分包含一些JS,可打开一个对话框。 When flipping between that portion and another, on opening the dialog for a second time things get messed up. 在该部分和另一部分之间切换时,第二次打开对话框时,事情变得一团糟。

Reason 原因

$el.dialog() removes the DOM element that is to become the popup ( $el[0] ) from its original place in the document hierarchy and appends it to the document body instead. $el.dialog()从文档层次结构中的原始位置删除将成为弹出窗口的DOM元素( $el[0] ),并将其附加到文档正文中。 When I then remove the popup element's original parent element, the popup element doesn't get removed. 然后,当我删除popup元素的原始父元素时,popup元素不会被删除。

This then means that doing this (changing / removing that portion of the page and then changing it back) all again results in duplicate element IDs which unsurprisingly confuses the hell out of the dialog widget. 然后,这意味着执行此操作(更改/删除页面的该部分,然后再将其更改回)全部导致重复的元素ID,这毫不奇怪地使对话框窗口小部件变得混乱。

Solution

I have come up with a solution that overrides the $.fn.dialog function and makes use of jQuery special events . 我想出了一个覆盖$.fn.dialog函数并利用jQuery 特殊事件的解决方案。 It attaches a listener to the custom event 'destroyed' on the original parent element, the 'destroyed' event is triggered when jQuery removes any element, the listener reacts to this event by removing the popup element wherever it now might be in the document heirarchy. 它将侦听器附加到原始父元素上的自定义事件“ destroyed”,当jQuery删除任何元素时触发“ destroyed”事件,侦听器通过删除popup元素对此事件做出反应,无论它现在位于文档层次结构中的何处。

Here it is: 这里是:

(function($) {

   $.event.special.destroyed = {
        remove: function(o) {
            if (o.handler) {
                o.handler.apply(this, arguments);
            }
        }
    };

    var originalDialogFn = $.fn.dialog;

    $.fn.dialog = function(firstArg) {
        if (!this.data('dialog') && firstArg != 'destroy' && !this.data('dialogCleaner')) {
            this.data('dialogCleaner', true);

            var $parent = this.parent();
            var $dialogEl = this;

            $parent.bind('destroyed', function(e) {
                if (this == $parent.get(0)) {
                    $dialogEl.remove();
                }
            });
        }

        return originalDialogFn.apply(this, arguments);
    };

})(jQuery);

Are there any better ways of doing this? 有没有更好的方法可以做到这一点? It seems like a slight flaw in the way the jQuery dialog works, in that it's not that easy to tidy it up nice and generically . jQuery对话框的工作方式似乎有点瑕疵,因为要很好地, 通用地整理它并不容易。

Of course I am aware of the dialog('destroy') method but doesn't seem particularly easy to hook that into my page fragment/portion handling. 我当然知道dialog('destroy')方法,但是将其挂接到页面片段/部分处理中似乎并不特别容易。

You could do what I do in these situations. 在这些情况下,您可以做我所做的事情。 Capture the parent element prior to making the dialog and then, after the dialog is created, detach it from the DOM and re-append it back to the parent element. 在创建对话框之前捕获父元素,然后在创建对话框之后,将其与DOM分离,然后将其重新添加回父元素。

var dlg = $('selector.dialog'),
    dlgParent = dlg.parent();

dlgParent.append(dlg.dialog().detach());

This works especially well when dealing with ASPX forms (because any server-side tags that I need to get a postback value from must remain within the form). 在处理ASPX表单时,这种方法特别有效(因为我需要从中获取回发值的任何服务器端标记都必须保留在表单内)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM