【发布时间】:2011-06-28 19:33:54
【问题描述】:
我有一个完全 ajaxed 的网站,它使用 jQuery 的 $.get 调用在标题点击时获取网站的中心内容。 其中一个“屏幕”(实际上是使用 Zend 的视图)有一个隐藏的 div,当用户单击某个按钮时会“对话”。这就是发生在我身上的事情:
- 我进入所需的屏幕,然后单击打开对话框按钮。
- 对话框打开正常。关闭和重新打开按预期工作。
- 我转到另一个屏幕(请注意,这是 ajax,它只是将主要内容替换为新内容 - 但是隐藏的 div 在此内容中,并与主要内容一起被替换)
- 我回到前一个屏幕(仍然是 ajaxing),然后再次单击打开对话框按钮。现在突然之间,有两个隐藏的 div,都具有相同的 ID(如果我执行 console.log($("div#hiddenDiv").length); ,我可以看到)并且它们都生成了以对话形式 - 我将它们放在一起。
当我重做此操作时,对话框会重复多次。如果我转到另一个屏幕,返回并再次打开对话框 - 我得到 3,等等。
我采取了很多预防措施——每次点击 ajax 时我都会清空内存,将所有与我无关的变量都设置为 null。我还注意在每个新的 ajax 调用(即屏幕转换)上替换整个内容,以及隐藏的 div。我检查并确保调用对话框的函数不会被多次调用 - 它只是在返回到默认情况下包含它的屏幕时复制对话框,我不知道为什么。请注意 - 没有其他元素被欺骗。只有这个隐藏的即将对话的 div。
另外值得注意的是,在我第一次打开对话框之前,复制过程永远不会开始。从那一刻起,每个 ajax [departure/return/dialog-opening] 方案都会欺骗不可见的 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. ajaxData 返回,并打开对话框,一切正常。
4. ajaxData 远离它。
5. ajaxData 返回并打开对话框,被骗了。
冲洗并重复,从现在开始他们被骗了。
编辑2:
我能够在 SummonDialog 函数中暂时破解这个问题:
var dialogBox = $("div#new_window");
var usableDialog = dialogBox[0];
$(dialogBox).remove();
$(usableDialog).dialog({
// ... dialog code as usual ...
但我不太喜欢这个解决方案。 Marc 的解释是有道理的,但由于我有许多不同的隐藏 div 有可能成为分散在许多不同视图中的对话框,因此以这种方式删除每个 div 将是乏味的,因为它们往往具有不同的上下文适当的 ID 并删除为“ ui-dialog-content" 类(所有 div 在打开对话框后都会得到)可能会在网站的其他部分产生一些问题,因为它的范围太笼统了。
【问题讨论】:
-
你能发布一个(简洁的)你的代码示例吗?
-
我的第一个倾向是您将
.dialog重新附加到隐藏的 div。在加载下一个“页面”内容之前,您可能需要致电$("selector").dialog("destroy")。 -
@MArc 试过了,没效果。 @Chris 是的,我会尽力在下一次编辑中发布一些有形的东西。
-
@Swader:那么也许您正在为对话框复制每个页面上的设置代码。
-
@Marc:我不这么认为,我确实确保我只调用一次。 div 就在.. 那里,在 phtml 中,实际上没有设置代码。刚刚发布了一些样本。差不多就是这个了,不过稍微缩写了。 div 只是 ajaxData 函数中“数据”数据中的普通隐藏 div。
标签: javascript jquery zend-framework dom dialog