如何停止 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 事件已经太晚了。