無論如何我都無法停止 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 生成回發。如何防止這種回發?

uj5u.com熱心網友回復:
好的,讓我們把一個簡單的例子放在一起來展示它是如何作業的。
我們將在表單上放置一個簡單的按鈕,并彈出一個對話框詢問您是或否。
所以,第一個例子,阻塞代碼(halting code)。
這個例子有效,因為名為 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 - 腳本的最后一行。
When we hit ok or cancel, then either of those stubs can run - but we ALREADY returned false to the server side button - it will not run, and our ok/cancel does nothing.
So, what is the solution here?
As noted, since this js code is asynchronous, then it can't wait.
There are two solutions I often use.
One trick, is I create a hidden button below the actual button, hide it, and then click on it. So I will have this:
<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"
/>
So, the 2nd button is hidden, and now our code is this:
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>
So, now if I hit ok, then I click the 2nd hidden button to run our code.
This is not all that bad but often I don't like to have to add that 2nd fake hidden button and click on. But, the above now does work.
If you hit ok, then post-back button code works.
If you hit cancel, then post-back button code does not work
We in effect really don't use the first button.
However, there is a another way!
I often now use this code, with just the one button.
<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>
So note what we do here.
The user clicks on button. The js (client side code) runs, pops the dialog (or does a ajax call, AND THEN AS NOTED RUNS RIGHT though to the end of the code and returns false.
So, this means the server side code button can't run, did not run, and will not run.
Now when the ajax call is done, returns (or in this case you answer the dialog), then we do this trick:
Ok: (function () {
mydiv.dialog("close")
mydelpromptok = true
btn.click()
So we set that global var = true. and now RE-FIRE the sever side button!! And I had to pass the button anyway, since I wanted the button to appear right below the button click (and to the right) by using the jQuery position here.
So, now what happens? The btn.click() fires the button, the button then call our SAME routine again but this time this occurs:
mydelpromptok = false
function mydelprompt2(btn) {
if (mydelpromptok) {
mydelpromptok = false
return true
}
So, now the SAME routine is called again (btn.click()), but since we set the global var = true, then the routine at start checks this value, and since it is true, we return that value, and the server side button code now runs. (and note that mydelpromptok = false ONLY runs on the page load, and first initialization of variables - not later on, and not each time code is called).
So, the same idea can be used with your code. When you return from the ajax call, set your flag = true, and "click()" that event again with the jQuery.Click() method. It will of course fire the routine to run again, and this time true is returned, and thus your server side button will run after the ajax call - even if the ajax call say takes 1-2 seconds, the code in a round about way waits, since the first time calling the js code DOES run through, does not halt (like most js code - rare exception was my first confirm() example, but that and alert() are about the only two things that actually halt js code.
So, most routines - including ajax calls do NOT halt code. That routine you call will run RIGHT through to the end of that routine and exit. When the ajax call is done, then the success code stub will NOW re-enter, and be re-run. It is at that point you have to THEN call server side code. As noted, you can do this with a fake button, a _doPostback() js command, or do what I did above. Use a click method.
Since in 9 out of 10 times, we want the button or click event to return true/false, then little harm occurred in fire the click event again, but this time we return true and the rest of that same routine does not run again.
You can write code that flows better by considering use of a "promise" in js, but you wind up with at least two separate routines, and you STILL have to find a way to trigger/call that click event. Other approaches involve "cancel event" or stop propagation of the button - but they can be messy to work with.
So, either extra hidden button - and click it when your ajax success runs, or stick to one simple event, and introduce that true/false flag.
I find for adding a confirm/yes/no dialog to existing asp.net buttons and click events the above approach works VERY well, since the button code, and original button event needs ZERO changes except for the addition of the client side click event, and that of returning true/false.
Give the above idea a try.
But, by non-blocking code, I simple mean that those js routines do NOT halt, run right though, and they are to be considered asynchronous code.
so in your example code, you need the last line to be return false so the button click does not run. You have to click again, and at the start of the routine return true and exit if you want the post back to run. Your code that follows to set true/false is of no value UNLESS we click the button or trigger that event again, since on first click - the js routine you have DOES NOT halt, nor wait - it runs right though to the end, and that's too late to return true/false to the sever side button/click event.
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/337979.html
