如何停止 ASP.NET 回发(return false、e.stopPropagation、e.cancelBubble)不起作用
How to stop ASP.NET postback (return false, e.stopPropagation, e.cancelBubble) don't working
无论如何我都无法阻止ASP.NET回发。任何已知方法(如 return false、stopPropagation、cancelBubble)都不起作用。我的代码:
<form method="post" action="./" id="Form1">
<div onclick="watch_auc('617135a1d1c02a8fd9a22a72',false);">
</form>
<script>
function watch_auc(idForm, watch) {
jQuery.post(...);
if (!e) var e = window.event;
e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
return false;
}
function ajaxDone() { ... }
</script>
我的站点也使用 jQuery,在我从函数 watch_auc() return 之后,我看到一个巨大的 jQuery 事件调度程序正在为我做一些误解。结果 jQuery 生成回传。
如何防止这种回发?
好的,让我们举一个简单的例子来说明这是如何工作的。
我们将在表单上放置一个简单的按钮,并弹出一个
询问您是或否的对话框。
所以,第一个示例,阻塞代码(停止代码)。
这个例子可行,因为调用HALTS的js等待输入,然后returns true or false。
我们有这个按钮 + 标记:
<asp:Button ID="cmdDelete" runat="server" Text="Delete Record" Width="112px" CssClass="btn"
OnClick="cmdDelete_Click"
OnClientClick="return mydelprompt()"
/>
<script>
function mydelprompt() {
return confirm("Delete record? ok")
}
</script>
所以当我们运行上面的时候,我们return值为true,或者为OnCientClick事件的false。如果我们 return 为真,那么服务器端按钮(和 post-back)将 运行.
我们的服务器端代码(post-back 上的 运行s)是这样的:
protected void cmdDelete_Click(object sender, EventArgs e)
{
Debug.Print("Server delete code will run");
// server side code here to delete record
}
因此,如果我们点击确定,那么将发生 post 返回(我们的按钮代码服务器端 运行s)。
因此,如果我们点击取消,则 return 为 false,因此不会发生 post-back,并且服务器端代码不会 运行.
好的,现在让我们用 ajax 调用或简单的 jquery.UI 对话框替换上面的确认。 (两者确实是同一个问题)。
我们现在有了这个代码:
<script>
function mydelprompt2(btn) {
var mydiv = $("#mydeldiv")
mydiv.dialog({
modal: true, appendTo: "form",
title: "delete", closeText: "",
width: "20%",
position: { my: 'left top', at: 'right bottom', of: btn },
buttons: {
Ok: (function () {
mydiv.dialog("close")
return true
}),
Cancel: (function () {
mydiv.dialog("close")
return false
})
}
});
return false;
}
</script>
那么,以上是否有效?
不!
为什么?
当我们点击我们的按钮时,上面的脚本 运行s,但是是异步的 - 它 运行s RIGHT THROUGH 没有任何暂停或等待代码,所以上面的最后一行脚本将 return 为假,我们的 post-back 不会发生,而且永远不会发生!!!
里面的代码
buttons: {
Ok: (function () {
mydiv.dialog("close")
return true
}),
Cancel: (function () {
mydiv.dialog("close")
return false
})
}
不相关,因为那些是回调。该代码将 运行、显示对话框并且还 return 对按钮单击设置为 false,因此不会 运行。
我们现在将看到:
但是,例程已经 return 错误 - 脚本的最后一行。
当我们点击确定或取消时,这些存根中的任何一个都可以 运行 - 但我们已经 return 对服务器端按钮设置了 false - 它不会 运行,并且我们的 ok/cancel 什么都不做。
那么,这里的解决方案是什么?
注意了,既然这段js代码是异步的,那就等不及了。
我经常使用的解决方案有两种。
一个技巧是,我在实际按钮下方创建一个隐藏按钮,将其隐藏,然后单击它。所以我要这个:
<asp:Button ID="cmdDelete" runat="server" Text="Delete Record" Width="112px" CssClass="btn"
OnClick="cmdDelete_Click"
OnClientClick="return mydelprompt2(this)"
/>
<asp:Button ID="cmdDeleteH" runat="server" Text="Delete Record" Width="112px" CssClass="btn"
OnClick="cmdDelete_Click"
Style="display:none"
ClientIDMode="Static"
/>
所以,第二个按钮被隐藏了,现在我们的代码是这样的:
function mydelprompt2(btn) {
var mydiv = $("#mydeldiv")
mydiv.dialog({
modal: true, appendTo: "form",
title: "delete", closeText: "",
width: "20%",
position: { my: 'left top', at: 'right bottom', of: btn },
buttons: {
Ok: (function () {
mydiv.dialog("close")
$("#cmdDeleteH").click()
}),
Cancel: (function () {
mydiv.dialog("close")
})
}
});
return false;
}
</script>
所以,现在如果我点击确定,然后我点击第二个隐藏按钮 运行 我们的代码。
这还不算太糟糕,但我通常不喜欢必须添加第二个假隐藏按钮并单击。但是,以上内容现在确实有效。
如果您点击“确定”,那么 post-back + 按钮代码有效。
如果您点击取消,那么 post-返回 + 按钮代码将不起作用
实际上我们真的不使用第一个按钮。
不过,还有一个办法!
我现在经常使用这个代码,只需一个按钮。
<script>
mydelpromptok = false
function mydelprompt2(btn) {
if (mydelpromptok) {
mydelpromptok = false
return true
}
var mydiv = $("#mydeldiv")
mydiv.dialog({
modal: true, appendTo: "form",
title: "delete", closeText: "",
width: "20%",
position: { my: 'left top', at: 'right bottom', of: btn },
buttons: {
Ok: (function () {
mydiv.dialog("close")
mydelpromptok = true
btn.click()
}),
Cancel: (function () {
mydiv.dialog("close")
})
}
});
return false;
}
</script>
所以请注意我们在这里所做的事情。
用户点击按钮。 js(客户端代码)运行s,弹出对话框(或执行 ajax 调用,然后按照说明正确运行到代码末尾,returns 错误。
所以,这意味着服务器端代码按钮不能 运行,没有 运行,也不会 运行。
现在,当 ajax 调用完成后,returns(或者在本例中您回答对话),然后我们执行以下操作:
Ok: (function () {
mydiv.dialog("close")
mydelpromptok = true
btn.click()
因此我们设置全局变量 = true。现在重新启动服务器侧按钮!!
无论如何我都必须通过按钮,因为我希望通过使用此处的 jQuery 位置使按钮显示在按钮单击的正下方(和右侧)。
那么,现在发生了什么? btn.click() 触发按钮,然后按钮再次调用我们的 SAME 例程,但这次发生了:
mydelpromptok = false
function mydelprompt2(btn) {
if (mydelpromptok) {
mydelpromptok = false
return true
}
所以,现在再次调用 SAME 例程 (btn.click()),但是由于我们设置了全局 var = true,所以开始时的例程会检查这个值,因为它是 true,我们return 那个值,服务器端按钮代码现在 运行s。
(请注意,mydelpromptok = false 仅在页面加载时 运行s 和变量的第一次初始化 - 不是稍后,也不是每次调用代码时)。
因此,同样的想法可以用于您的代码。
当您从 ajax 调用中 return 时,将您的标志设置为 true,然后使用 jQuery.Click() 方法再次“单击()”该事件。它当然会再次将例程触发到 运行,这次是 returned,因此您的服务器端按钮将在 ajax 调用之后 运行 - 即使ajax 调用 say 需要 1-2 秒,循环方式中的代码等待,因为第一次调用 js 代码确实 运行 通过,不会停止(像大多数 js 代码一样 - 罕见的例外是我的第一个 confirm() 示例,但那和 alert() 是唯一真正停止 js 代码的两件事。
因此,大多数例程 - 包括 ajax 调用不会停止代码。您调用的例程将 运行 一直到该例程结束并退出。 ajax 调用完成后,成功代码存根现在将重新输入,并重新 运行。就在那时你必须然后调用服务器端代码。如前所述,您可以使用假按钮、_doPostback() js 命令或执行我在上面所做的操作来执行此操作。使用点击方法。
由于10次中有9次,我们希望按钮或点击事件return true/false,那么再次触发点击事件几乎没有什么坏处,但是这次我们return true 并且相同例程的其余部分不会再次 运行。
您可以通过考虑在 js 中使用“promise”来编写更流畅的代码,但您最终会得到至少两个单独的例程,并且您仍然必须找到一种方法来 trigger/call 单击事件。其他方法涉及“取消事件”或停止传播按钮 - 但使用它们可能会很麻烦。
因此,要么额外隐藏按钮 - 然后在 ajax 成功 运行 时单击它,要么坚持一个简单的事件,并引入那个 true/false 标志。
我发现要将 confirm/yes/no 对话框添加到现有 asp.net 按钮和单击事件,上述方法非常有效,因为按钮代码和原始按钮事件需要零更改,除了添加客户端点击事件,以及 returning true/false.
试试上面的想法。
但是,对于非阻塞代码,我简单的意思是那些 js 例程不会停止,运行 但是,它们将被视为异步代码。
所以在你的示例代码中,你需要最后一行是 return false 这样按钮点击就不会 运行。您必须再次单击,如果您希望 post 返回 运行,则在例程开始时 return 为 true 并退出。除非我们单击按钮或再次触发该事件,否则您设置 true/false 之后的代码没有任何价值,因为在第一次单击时 - 您拥有的 js 例程不会停止,也不会等待 - 它 运行s虽然一直到最后,但是 return true/false 到服务器端 button/click 事件已经太晚了。
无论如何我都无法阻止ASP.NET回发。任何已知方法(如 return false、stopPropagation、cancelBubble)都不起作用。我的代码:
<form method="post" action="./" id="Form1">
<div onclick="watch_auc('617135a1d1c02a8fd9a22a72',false);">
</form>
<script>
function watch_auc(idForm, watch) {
jQuery.post(...);
if (!e) var e = window.event;
e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
return false;
}
function ajaxDone() { ... }
</script>
我的站点也使用 jQuery,在我从函数 watch_auc() return 之后,我看到一个巨大的 jQuery 事件调度程序正在为我做一些误解。结果 jQuery 生成回传。 如何防止这种回发?
好的,让我们举一个简单的例子来说明这是如何工作的。
我们将在表单上放置一个简单的按钮,并弹出一个 询问您是或否的对话框。
所以,第一个示例,阻塞代码(停止代码)。
这个例子可行,因为调用HALTS的js等待输入,然后returns true or false。
我们有这个按钮 + 标记:
<asp:Button ID="cmdDelete" runat="server" Text="Delete Record" Width="112px" CssClass="btn"
OnClick="cmdDelete_Click"
OnClientClick="return mydelprompt()"
/>
<script>
function mydelprompt() {
return confirm("Delete record? ok")
}
</script>
所以当我们运行上面的时候,我们return值为true,或者为OnCientClick事件的false。如果我们 return 为真,那么服务器端按钮(和 post-back)将 运行.
我们的服务器端代码(post-back 上的 运行s)是这样的:
protected void cmdDelete_Click(object sender, EventArgs e)
{
Debug.Print("Server delete code will run");
// server side code here to delete record
}
因此,如果我们点击确定,那么将发生 post 返回(我们的按钮代码服务器端 运行s)。
因此,如果我们点击取消,则 return 为 false,因此不会发生 post-back,并且服务器端代码不会 运行.
好的,现在让我们用 ajax 调用或简单的 jquery.UI 对话框替换上面的确认。 (两者确实是同一个问题)。
我们现在有了这个代码:
<script>
function mydelprompt2(btn) {
var mydiv = $("#mydeldiv")
mydiv.dialog({
modal: true, appendTo: "form",
title: "delete", closeText: "",
width: "20%",
position: { my: 'left top', at: 'right bottom', of: btn },
buttons: {
Ok: (function () {
mydiv.dialog("close")
return true
}),
Cancel: (function () {
mydiv.dialog("close")
return false
})
}
});
return false;
}
</script>
那么,以上是否有效?
不! 为什么?
当我们点击我们的按钮时,上面的脚本 运行s,但是是异步的 - 它 运行s RIGHT THROUGH 没有任何暂停或等待代码,所以上面的最后一行脚本将 return 为假,我们的 post-back 不会发生,而且永远不会发生!!!
里面的代码
buttons: {
Ok: (function () {
mydiv.dialog("close")
return true
}),
Cancel: (function () {
mydiv.dialog("close")
return false
})
}
不相关,因为那些是回调。该代码将 运行、显示对话框并且还 return 对按钮单击设置为 false,因此不会 运行。
我们现在将看到:
但是,例程已经 return 错误 - 脚本的最后一行。
当我们点击确定或取消时,这些存根中的任何一个都可以 运行 - 但我们已经 return 对服务器端按钮设置了 false - 它不会 运行,并且我们的 ok/cancel 什么都不做。
那么,这里的解决方案是什么?
注意了,既然这段js代码是异步的,那就等不及了。
我经常使用的解决方案有两种。
一个技巧是,我在实际按钮下方创建一个隐藏按钮,将其隐藏,然后单击它。所以我要这个:
<asp:Button ID="cmdDelete" runat="server" Text="Delete Record" Width="112px" CssClass="btn"
OnClick="cmdDelete_Click"
OnClientClick="return mydelprompt2(this)"
/>
<asp:Button ID="cmdDeleteH" runat="server" Text="Delete Record" Width="112px" CssClass="btn"
OnClick="cmdDelete_Click"
Style="display:none"
ClientIDMode="Static"
/>
所以,第二个按钮被隐藏了,现在我们的代码是这样的:
function mydelprompt2(btn) {
var mydiv = $("#mydeldiv")
mydiv.dialog({
modal: true, appendTo: "form",
title: "delete", closeText: "",
width: "20%",
position: { my: 'left top', at: 'right bottom', of: btn },
buttons: {
Ok: (function () {
mydiv.dialog("close")
$("#cmdDeleteH").click()
}),
Cancel: (function () {
mydiv.dialog("close")
})
}
});
return false;
}
</script>
所以,现在如果我点击确定,然后我点击第二个隐藏按钮 运行 我们的代码。
这还不算太糟糕,但我通常不喜欢必须添加第二个假隐藏按钮并单击。但是,以上内容现在确实有效。
如果您点击“确定”,那么 post-back + 按钮代码有效。
如果您点击取消,那么 post-返回 + 按钮代码将不起作用
实际上我们真的不使用第一个按钮。
不过,还有一个办法!
我现在经常使用这个代码,只需一个按钮。
<script>
mydelpromptok = false
function mydelprompt2(btn) {
if (mydelpromptok) {
mydelpromptok = false
return true
}
var mydiv = $("#mydeldiv")
mydiv.dialog({
modal: true, appendTo: "form",
title: "delete", closeText: "",
width: "20%",
position: { my: 'left top', at: 'right bottom', of: btn },
buttons: {
Ok: (function () {
mydiv.dialog("close")
mydelpromptok = true
btn.click()
}),
Cancel: (function () {
mydiv.dialog("close")
})
}
});
return false;
}
</script>
所以请注意我们在这里所做的事情。
用户点击按钮。 js(客户端代码)运行s,弹出对话框(或执行 ajax 调用,然后按照说明正确运行到代码末尾,returns 错误。
所以,这意味着服务器端代码按钮不能 运行,没有 运行,也不会 运行。
现在,当 ajax 调用完成后,returns(或者在本例中您回答对话),然后我们执行以下操作:
Ok: (function () {
mydiv.dialog("close")
mydelpromptok = true
btn.click()
因此我们设置全局变量 = true。现在重新启动服务器侧按钮!! 无论如何我都必须通过按钮,因为我希望通过使用此处的 jQuery 位置使按钮显示在按钮单击的正下方(和右侧)。
那么,现在发生了什么? btn.click() 触发按钮,然后按钮再次调用我们的 SAME 例程,但这次发生了:
mydelpromptok = false
function mydelprompt2(btn) {
if (mydelpromptok) {
mydelpromptok = false
return true
}
所以,现在再次调用 SAME 例程 (btn.click()),但是由于我们设置了全局 var = true,所以开始时的例程会检查这个值,因为它是 true,我们return 那个值,服务器端按钮代码现在 运行s。 (请注意,mydelpromptok = false 仅在页面加载时 运行s 和变量的第一次初始化 - 不是稍后,也不是每次调用代码时)。
因此,同样的想法可以用于您的代码。 当您从 ajax 调用中 return 时,将您的标志设置为 true,然后使用 jQuery.Click() 方法再次“单击()”该事件。它当然会再次将例程触发到 运行,这次是 returned,因此您的服务器端按钮将在 ajax 调用之后 运行 - 即使ajax 调用 say 需要 1-2 秒,循环方式中的代码等待,因为第一次调用 js 代码确实 运行 通过,不会停止(像大多数 js 代码一样 - 罕见的例外是我的第一个 confirm() 示例,但那和 alert() 是唯一真正停止 js 代码的两件事。
因此,大多数例程 - 包括 ajax 调用不会停止代码。您调用的例程将 运行 一直到该例程结束并退出。 ajax 调用完成后,成功代码存根现在将重新输入,并重新 运行。就在那时你必须然后调用服务器端代码。如前所述,您可以使用假按钮、_doPostback() js 命令或执行我在上面所做的操作来执行此操作。使用点击方法。
由于10次中有9次,我们希望按钮或点击事件return true/false,那么再次触发点击事件几乎没有什么坏处,但是这次我们return true 并且相同例程的其余部分不会再次 运行。
您可以通过考虑在 js 中使用“promise”来编写更流畅的代码,但您最终会得到至少两个单独的例程,并且您仍然必须找到一种方法来 trigger/call 单击事件。其他方法涉及“取消事件”或停止传播按钮 - 但使用它们可能会很麻烦。
因此,要么额外隐藏按钮 - 然后在 ajax 成功 运行 时单击它,要么坚持一个简单的事件,并引入那个 true/false 标志。
我发现要将 confirm/yes/no 对话框添加到现有 asp.net 按钮和单击事件,上述方法非常有效,因为按钮代码和原始按钮事件需要零更改,除了添加客户端点击事件,以及 returning true/false.
试试上面的想法。
但是,对于非阻塞代码,我简单的意思是那些 js 例程不会停止,运行 但是,它们将被视为异步代码。
所以在你的示例代码中,你需要最后一行是 return false 这样按钮点击就不会 运行。您必须再次单击,如果您希望 post 返回 运行,则在例程开始时 return 为 true 并退出。除非我们单击按钮或再次触发该事件,否则您设置 true/false 之后的代码没有任何价值,因为在第一次单击时 - 您拥有的 js 例程不会停止,也不会等待 - 它 运行s虽然一直到最后,但是 return true/false 到服务器端 button/click 事件已经太晚了。