如何停止 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 验证后停止回发

防止 ASP.net __doPostback() 来自 UpdatePanel 中的 jQuery submit()

asp.net textarea 换行和防止回发返回键

在没有回发的情况下重置 ASP.NET 中的页面

如何使用带有 asp.net 的 jQuery 进行 onclientclick 回发