jQuery 对话框 - 在 ajax 站点上复制一个独特的对话框

发布于 2024-11-17 23:17:13 字数 2961 浏览 1 评论 0原文

我有一个完全ajax 的网站,它使用 jQuery 的 $.get 调用在标题单击时获取网站的中心内容。 其中一个“屏幕”(实际上是使用 Zend 的视图)有一个隐藏的 div,当用户单击某个按钮时,会“对话”该 div。这就是发生在我身上的事情:

  1. 我到达所需的屏幕,然后单击“打开对话框”按钮。
  2. 对话框打开正常。关闭和重新开放工作按预期进行。
  3. 我转到另一个屏幕(请注意,这是 ajax,它只是用新内容替换主要内容 - 然而,隐藏的 div 位于该内容内,并且与主要内容一起被替换)
  4. 我回到上一个屏幕(仍然是ajax),然后再次单击“打开对话框”按钮。现在突然之间,有两个隐藏的 div,它们都具有相同的 ID(我可以看到,如果我执行 console.log($("div#hiddenDiv").length); ),并且它们都会生成以对话框形式 - 我将它们放在一起。

当我重做此操作时,对话框会重复多次。如果我转到另一个屏幕,返回并再次打开对话框 - 我得到 3 等。

我采取了很多预防措施 - 我在每次 ajax 单击时清空内存,将所有与我无关的变量设置为 null。我还小心地在每个新的 ajax 调用(即屏幕转换)上替换整个内容,以及隐藏的 div。我检查并确保调用对话框的函数不会被多次调用 - 它只是在返回到默认包含它的屏幕时复制对话框,我不知道为什么。请注意 - 没有其他元素被欺骗。只有这个隐藏的即将对话的 div。

另外值得注意的是,直到我第一次打开对话框时,欺骗过程才开始。从那一刻起,每个 ajax [出发/返回/对话框打开] 方案都会欺骗不可见的 div。

有谁知道为什么会发生这种情况?

编辑:代码示例:

// This causes the screen change when it detects a hash change
// ... stuff ...
if(window.location.hash){
            ajaxData(newhash);
        }
// ... stuff ...


// This causes the actual change of on-screen content (i.e. this is the ajax call) 
function ajaxData(value) {
// ... stuff ...
$.ajax({
    url: "/siteexample/"+value,
    type: "GET",
    mode: "abort",
    dataType: type,
    success: function(data){
        $("#main_content").html(data); // the hidden div is always inside this "data", so it always gets removed when a new screen loads
        loaderdisplay('hide');
        // Clean Memory
        data = null;
    },
    data: ({ajax : 'Y'})
   });
    // ... stuff ....


// And finally, this is the part that summons the dialog
function summonDialog() {
    console.log("here"); // this shows up only once, so I know this function is not called multiple times.
    var dialogBox = $("div#new_window"); // this is the infamous div
    $(dialogBox).dialog({
        modal: true,
        title: "Some title",
        resizable: false,
        zIndex: 22000,
        width: 800,
        buttons: {
            "Save": function(){
                 // some function, ends with:
                 $(dialogBox).dialog("close"); // destroy doesn't change anything
                 dialogBox = null;
            },
            Cancel: function(){
                $(this).dialog("close"); // destroy doesn't change anything
                dialogBox = null;
            }
        }
    });
}

所以事件的顺序是:
1. ajaxData到div所在位置。
2. ajaxData远离它。
3. ajax数据返回,并打开对话框,一切正常。
4. ajaxData远离它。
5. ajaxData返回并打开对话框,被骗了。
冲洗并重复,从现在开始他们就被骗了。

编辑2:
我能够暂时将其破解为在 SummonDialog 函数中使用此修复程序:

var dialogBox = $("div#new_window");
            var usableDialog = dialogBox[0];
            $(dialogBox).remove();
            $(usableDialog).dialog({
// ... dialog code as usual ...

但我不太喜欢该解决方案。马克的解释是有道理的,但由于我有许多不同的隐藏 div,有可能成为分散在许多不同视图中的对话框,因此以这种方式删除每个隐藏 div 会很乏味,因为它们往往具有不同的适合上下文的 ID,并通过“删除” ui-dialog-content”类(所有 div 在打开对话框后都会获得)可能会在网站的其他部分产生一些问题,因为它的范围太宽泛。

I have a fully ajaxed website, which uses jQuery's $.get calls to fetch the central content of the website upon header clicks.
One of the "screens" (views, actually, using Zend) has a hidden div which is "dialoged" when a user clicks a certain button. This is what happens to me:

  1. I get to the desired screen, and click the open dialog button.
  2. Dialog opens fine. Closing and reopening works as expected.
  3. I go to another screen (mind you, this is ajax, which simply replaces the main content with new content - the hidden div is inside this content, however, and gets replaced along with the main content)
  4. I come back to the previous screen (still ajaxing), and click the open dialog button again. Now all of a sudden, there are two of those hidden divs, both with the identical ID (I can see that if I do a console.log($("div#hiddenDiv").length); ) and they are both spawned in dialog form - I have them on top of each other.

The dialogs get duplicated for as many times as I redo this. If I go to another screen, come back, and open dialog again - I get 3, etc.

I took a lot of precautions - I empty the memory at every ajax click, setting all variables I have nothing to do with anymore to null. I also take care to replace the entire content, the hidden divs as well, on every new ajax call, i.e. screen-transition. I checked and made sure that the function which summons the dialog isn't called more than once - it simply dupes the dialog upon returning to the screen which contains it by default, and I have no idea why. Mind you - no other element is duped. Only this hidden soon-to-be-dialog div.

Also worth noting is the fact that the duping process never begins until I open the dialog for the first time. From that moment on, every ajax [departure/return/dialog-opening]-scheme dupes the invisible div.

Does anyone have any idea why this is happening?

Edit: Code example:

// This causes the screen change when it detects a hash change
// ... stuff ...
if(window.location.hash){
            ajaxData(newhash);
        }
// ... stuff ...


// This causes the actual change of on-screen content (i.e. this is the ajax call) 
function ajaxData(value) {
// ... stuff ...
$.ajax({
    url: "/siteexample/"+value,
    type: "GET",
    mode: "abort",
    dataType: type,
    success: function(data){
        $("#main_content").html(data); // the hidden div is always inside this "data", so it always gets removed when a new screen loads
        loaderdisplay('hide');
        // Clean Memory
        data = null;
    },
    data: ({ajax : 'Y'})
   });
    // ... stuff ....


// And finally, this is the part that summons the dialog
function summonDialog() {
    console.log("here"); // this shows up only once, so I know this function is not called multiple times.
    var dialogBox = $("div#new_window"); // this is the infamous div
    $(dialogBox).dialog({
        modal: true,
        title: "Some title",
        resizable: false,
        zIndex: 22000,
        width: 800,
        buttons: {
            "Save": function(){
                 // some function, ends with:
                 $(dialogBox).dialog("close"); // destroy doesn't change anything
                 dialogBox = null;
            },
            Cancel: function(){
                $(this).dialog("close"); // destroy doesn't change anything
                dialogBox = null;
            }
        }
    });
}

So the sequence of events is:
1. ajaxData to the location where the div is.
2. ajaxData away from it.
3. ajaxData back, and open dialog, everything fine.
4. ajaxData away from it.
5. ajaxData back and open dialog, duped.
Rinse and repeat, from now on they're getting duped.

Edit2:
I was able to temporarily hack this into a fix with this in the summonDialog function:

var dialogBox = $("div#new_window");
            var usableDialog = dialogBox[0];
            $(dialogBox).remove();
            $(usableDialog).dialog({
// ... dialog code as usual ...

But I don't like the solution much. Marc's explanation makes sense, but since I have many different hidden divs with the potential to become dialogs scattered across many different views, removing each one in such a way would be tedious, since they tend to have different context-appropriate IDs and removing by "ui-dialog-content" class (which all divs get once they're dialog-opened) could produce some issues in other parts of the site, since it's a too general scope.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱情眠于流年 2024-11-24 23:17:13

我相信作为对话框的 div 将附加并隐藏在主体上。因此,当您替换 #main_content html 时,您并没有真正删除它。我建议删除 div 并在每次 html(data) 重新加载时重新启用 .dialog 插件。

像这样的事情:

  success: function(data){
        $("#new_window").remove();            
        $("#main_content").html(data); 
        loaderdisplay('hide');
        summonDialog();
  }

测试这个的简单方法是当你被骗时,简单地 console.log($("#new_window").length);

I believe the div that is the dialog will be attached and hidden on the body. Thus, when you replace the #main_content html, you're not really removing it. I would recommend removing the div and re-enabling the .dialog plugin on each html(data) reload.

Something like this:

  success: function(data){
        $("#new_window").remove();            
        $("#main_content").html(data); 
        loaderdisplay('hide');
        summonDialog();
  }

And easy way to test this is to simply console.log($("#new_window").length); when you get dupes.

零度° 2024-11-24 23:17:13

我遇到了完全相同的问题,即使在之后,对话框仍然重复,

$('.content').html('');

所以我添加了以下内容:

$("#divEditAdvice").remove(); 

这就是上面提到的@Marc 的解决方案。

I had exactly the same problem, The dialog was duplicated even after

$('.content').html('');

So I added this:

$("#divEditAdvice").remove(); 

That was the solution as @Marc mention above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文