如何停止 ASP.NET 回发(返回 false、e.stopPropagation、e.cancelBubble)不起作用
Posted
技术标签:
【中文标题】如何停止 ASP.NET 回发(返回 false、e.stopPropagation、e.cancelBubble)不起作用【英文标题】:How to stop ASP.NET postback (return false, e.stopPropagation, e.cancelBubble) don't working 【发布时间】:2021-12-10 10:47:35 【问题描述】:无论如何我都无法停止 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() 返回后,我看到一个巨大的 jQuery 事件调度程序在做什么对我有误解。结果 jQuery 生成回发。 如何防止这种回发?
【问题讨论】:
但是那个js代码并没有停止,因此即时一直运行,并且会返回false。在第一次运行。然后发生 ajax 调用,然后第二个例程成功运行。所以,你必须考虑非阻塞代码。该 js 代码在第一次运行时不会停止,并且在第一次调用/使用 click 事件时直接落在最后一行代码。 @AlbertD.Kallal,对不起,我可以在浏览器调试器中逐行跟踪我的函数 watch_auc() 并且我没有看到任何异常。在我的函数结束后,jQuery 事件调度程序开始工作。非阻塞代码是什么意思? 通过非阻塞代码,js函数caledl on click不会停止。代码将在单击时运行,并且 EXIT + 会返回到最后一行并返回 false。现在 jajax/post 运行,第二个例程运行成功。 js 代码不会停止,也不会等待帖子完成。该例程将在第一次单击时运行到最后。并且由于最后一行是 return false,那么这就是应该和将会发生的事情。因此,通过没有阻塞,该 js 例程不会停止,而是一直运行到最后并返回 false,因此服务器端单击事件将不会运行,因为它需要返回 true @AlbertD.Kallal 我必须停止回发什么?在 ajaxDone 的末尾插入相同的三个阻止行(return false、stopPropagation、cancelBubble)? div 不是发帖 - 这是你发帖的地方jQuery.post(
【参考方案1】:
好的,让我们举一个简单的例子来展示它是如何工作的。
我们将在表单上放置一个简单的按钮,然后弹出一个 询问您是或否的对话框。
所以,第一个例子,阻塞代码(停止代码)。
这个例子行得通,因为叫做 HALTS 的 js 等待输入,然后返回 true 或 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>
因此,当我们在上面运行时,我们为 OnCientClick 事件返回 true 或 false 值。如果我们返回 true,那么服务器端按钮(和回发)将运行。
我们的服务器端代码(在回发时运行)是这样的:
protected void cmdDelete_Click(object sender, EventArgs e)
Debug.Print("Server delete code will run");
// server side code here to delete record
所以,如果我们点击确定,那么将发生回发(我们的按钮代码服务器端运行)。
因此,如果我们点击取消,则返回 false,因此不会发生回发,并且服务器端代码不会运行。
好的,现在让我们用 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>
那么,上述方法是否可行?
不! 为什么?
当我们点击我们的按钮时,上面的脚本会运行,但是是异步的——它直接运行,没有任何暂停或等待代码,所以上面脚本的最后一行将返回 false,而我们的回发不会发生,而且永远不会发生!!!
里面的代码
buttons:
Ok: (function ()
mydiv.dialog("close")
return true
),
Cancel: (function ()
mydiv.dialog("close")
return false
)
不相关,因为那些是回调。代码将运行,显示对话框,并且还返回 false 到按钮单击,因此不会运行。
我们现在将看到:
但是,例程已经返回 false - 脚本的最后一行。
当我们点击 ok 或 cancel 时,这些存根中的任何一个都可以运行 - 但我们已经向服务器端按钮返回 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>
所以,现在如果我点击确定,然后我点击第二个隐藏按钮来运行我们的代码。
这并不是那么糟糕,但我通常不喜欢添加第二个假隐藏按钮并单击。但是,以上方法现在确实有效。
如果你点击 ok,那么 post-back + 按钮代码就可以工作了。
如果你点击取消,那么 post-back + 按钮代码不起作用
我们实际上并不使用第一个按钮。
但是,还有另一种方法!
我现在经常使用这个代码,只需一个按钮。
<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(客户端代码)运行,弹出对话框(或进行 ajax 调用,然后按说明运行到代码末尾并返回 false。
所以,这意味着服务器端代码按钮不能运行,没有运行,也不会运行。
现在,当 ajax 调用完成,返回(或者在这种情况下你回答对话框),然后我们做这个技巧:
Ok: (function ()
mydiv.dialog("close")
mydelpromptok = true
btn.click()
所以我们设置全局 var = true。现在重新启动服务器侧按钮! 无论如何我都必须传递按钮,因为我希望通过使用此处的 jQuery 位置,按钮显示在按钮单击的正下方(和右侧)。
那么,现在会发生什么? btn.click() 触发按钮,然后按钮再次调用我们的 SAME 例程,但这一次发生了:
mydelpromptok = false
function mydelprompt2(btn)
if (mydelpromptok)
mydelpromptok = false
return true
所以,现在再次调用 SAME 例程 (btn.click()),但是由于我们设置了全局 var = true,所以例程在开始时会检查这个值,因为它是 true,所以我们返回那个值,服务器端按钮代码现在运行。 (请注意,mydelpromptok = false 仅在页面加载和变量的第一次初始化时运行 - 不是稍后,也不是每次调用代码时)。
因此,您的代码可以使用相同的想法。 当您从 ajax 调用返回时,设置您的 flag = true,然后使用 jQuery.Click() 方法再次“click()”该事件。它当然会触发例程再次运行,这一次返回 true,因此您的服务器端按钮将在 ajax 调用之后运行 - 即使 ajax 调用说需要 1-2 秒,代码也是如此等待,因为第一次调用 js 代码确实运行,不会停止(像大多数 js 代码一样 - 罕见的例外是我的第一个 confirm() 示例,但那和 alert() 是唯一真正停止 js 代码的两件事.
因此,大多数例程 - 包括 ajax 调用都不会停止代码。您调用的该例程将一直运行到该例程的末尾并退出。 ajax 调用完成后,成功代码存根现在将重新输入,并重新运行。那时你必须调用服务器端代码。如前所述,您可以使用假按钮、_doPostback() js 命令来执行此操作,或者执行我上面所做的操作。使用点击方式。
因为在 10 次中有 9 次中,我们希望按钮或单击事件返回 true/false,所以再次触发 click 事件时几乎没有什么坏处,但这次我们返回 true,并且同一例程的其余部分没有再次运行。
您可以通过考虑在 js 中使用“promise”来编写更流畅的代码,但是您最终会得到至少两个独立的例程,并且您仍然必须找到一种方法来触发/调用该点击事件。其他方法涉及“取消事件”或停止按钮的传播 - 但使用起来可能会很麻烦。
所以,要么额外隐藏按钮 - 并在 ajax 成功运行时单击它,要么坚持一个简单的事件,并引入该真/假标志。
我发现要向现有的 asp.net 按钮和单击事件添加确认/是/否对话框,上述方法效果很好,因为按钮代码和原始按钮事件需要零更改,除了添加客户端点击事件,以及返回真/假。
试试上面的想法。
但是,通过非阻塞代码,我的意思是那些 js 例程不会停止,但可以正常运行,它们被视为异步代码。
所以在您的示例代码中,您需要将最后一行返回 false,以便按钮单击不会运行。您必须再次单击,如果您希望帖子重新运行,则在例程开始时返回 true 并退出。除非我们单击按钮或再次触发该事件,否则您设置 true/false 的代码没有任何价值,因为在第一次单击时 - 您拥有的 js 例程不会停止,也不会等待 - 它一直运行到最后,并且为服务器端按钮/单击事件返回 true/false 为时已晚。
【讨论】:
以上是关于如何停止 ASP.NET 回发(返回 false、e.stopPropagation、e.cancelBubble)不起作用的主要内容,如果未能解决你的问题,请参考以下文章
ASP.Net 脚本控件,从 OnClick 和 FireFox 返回 False
在 ASP.NET 代码中通过 javascript 重置 Jquery 验证后停止回发