Javascript-Ereignisse nicht auslösen in der erwarteten Reihenfolge

So, ich habe noch ein anderes kleines JavaScript Problem mit meinem aktuellen Projekt: JS Ereignisse sind nicht feuern in der Reihenfolge, wie ich es erwartet habe.

Sagen wir, ich habe ein Textfeld mit einem onBlur-Ereignis, das ausgelöst wird ein AJAX-Aufruf, erfolgt eine Berechnung auf dem server (ich bin mit .NET 3.5 Web Services mit JSON). Seine callback-Methode füllt eine Seite voller text-Felder mit den Ergebnissen aus der Berechnung.

Ich habe auch eine Schaltfläche mit einem onClick-Ereignis initiiert, die eine andere Berechnung, aber es beruht auf dem Abschluss des Textfeldes onBlur-Ereignis(s), bevor die Ergebnisse der onClick-Ereignis gültig wird.

Habe ich eine einfache mutex-die funktioniert auch Recht gut, bis die folgende situation: Der Benutzer ändert einen Wert in einem der Textfelder hat aber noch nicht verlassen, so konzentrieren sich immer noch auf das text-Feld. Während das Textfeld den Fokus hat, werden Sie auf eine Schaltfläche klicken, die hat ein onClick event. Mehr als oft nicht, der browser (IE7 in diesem Fall) feuert das onClick-Ereignis der Schaltfläche, BEVOR Sie das onBlur-Ereignis für das Textfeld!

Dies bewirkt, dass einige Chaos, und ich habe keine Ahnung, wie das durchzusetzen, um die Reihenfolge der Ereignisse ausgelöst wird. Meine kleine mutex funktioniert wie folgt: wenn die Ereignisse ausgelöst werden, setze ich ein flag, das bedeutet "warten auf den Rückruf." Alle nachfolgenden Ereignisse, Feuer, überprüfen Sie die fahne, bevor etwas zu tun. In der callback-ein zurücksetzen der flag auf "false".

So, irgendwelche Ideen? Ich denke, ich möchte fast alle web-service-Aufrufe synchron, aber ich weiß nicht, ob es eine einfache Möglichkeit, das zu tun.

Andere Dinge, die ich versucht habe, oder Dinge, die Sie wissen sollten:
- Deaktivieren Sie die Schaltflächen in der onBlur der Textfelder-Ihre onClicks noch Feuer, bevor Sie deaktiviert
- Denken Sie daran, dies geschieht nur, wenn der Bearbeitung ein Textfeld und sofort Klick auf eine Schaltfläche. Wenn der Benutzer klickt auf den leeren Raum, um das Feuer der onBlur-text-Feld, bevor Sie auf die Schaltfläche, es funktioniert alles perfekt.

EDIT:

Nachdem Sie einige Kommentare und mehr Tests hier ist, was ich möchte in der Lage sein zu tun:

In der onBlur des Textfeldes ich den deaktivieren-button, so dass Sie die onClick-Ereignis nicht ausgelöst. Allerdings, wenn ich code auf, das onBlur-Ereignis ausgelöst wird, ich kann sehen, dass die Schaltfläche immer deaktiviert, aber die onClick-Ereignis ist immer noch feuern.

Hier einige Beispiel-code. Manchmal das onClick-Ereignis passiert, und manchmal nicht. Wenn Sie die setTimeout-500 MS oder so, es scheint immer zu verhindern. Vielleicht ist das eine option...

<html>
<head>
<script type="text/javascript">

var onClickFlag = false;

function whatHappensOnFocus(el) {
    log('whatHappensOnFocus(): TextField focused.');
    onClickFlag = false;
    log('whatHappensOnFocus(): Set onClickFlag = false');
}

function whatHappensOnBlur(el) {
    log('whatHappensOnBlur(): TextField blurred.');
    document.getElementById('theButton').disabled = true;
    log('whatHappensOnBlur(): Disabled the Button');
    setTimeout(function() { someTestFieldFunction(); log('whatHappensOnBlur(): OnBlur callback called: someTestFieldFunction()'); }, 50);
    log ('whatHappensOnBlur(): setTimeout for someTestFieldFunction() for 50ms');
}

function log(msg) {
    document.getElementById('log').value += ('[' + (new Date().getTime()).toString() + '] ' + msg + '\n');
}

function someTestFieldFunction() {
    log('someTestFieldFunction(): Inside someTestFieldFunction()');
    log('someTestFieldFunction(): Test: onClickFlag = ' + onClickFlag);
    //alert('you blurred the text field.');
    //alert('onClickFlag = ' + onClickFlag);
    setTimeout(enableButton, 50);
    log('someTestFieldFunction(): setTimeout for enableButton()');
}

function enableButton() {
    document.getElementById('theButton').disabled = false;
    log('enableButton(): Button re-enabled');
    //onClickFlag = false;
}

function whatHappensOnClick(el) {
    log('whatHappensOnClick(): the Button onClick fired');
    someFunction();
    log('whatHappensOnClick(): someFunction() called');
}

function whatHappensOnMouseDown(el) {
    log('whatHappensOnMouseDown(): inside whatHappensOnMouseDown()');
    onClickFlag = true;
    log("whatHappensOnMouseDown(): set onClickFlag = true");
}

function someFunction() {
    log('someFunction(): inside someFunction()');
    log('someFunction(): You have successfully clicked the button');
    //alert("you clicked me! this shouldn't happen!")
}

</script>
</head>
<body>
<form id="testform">
<input type="text" size="10" onfocus="whatHappensOnFocus(this);" onblur="whatHappensOnBlur(this);" />
<br />
<br />
<input id="theButton" type="button" onmousedown="whatHappensOnMouseDown(this);" onmouseout="onClickFlag = false;" value="calculate" onclick="whatHappensOnClick(this);" />
<br />
<br />
<textarea rows="15" cols="100" id="log" style="overflow: scroll"></textarea>
<input type="reset" value="clear" />
</form>
</body>
</html>

UPDATE:

Ich aktualisiert, der code, den ich gepostet reflektieren einige der Problem, so dass Sie sehen können, wie ich diese getestet. Wenn Sie den Fokus auf ein Textfeld und klicken Sie auf eine Schaltfläche, wird das onMouseDown-Ereignis der Schaltfläche feuert, BEVOR das onBlur-Ereignis des Textfelds. Da kann ich ein flag setzen, so dass ich weiß, Sie haben versucht, auf die Schaltfläche klicken. Dann in der onSuccess-callback-event des AJAX-Aufruf ausgelöst durch das onBlur-Ereignis für das Textfeld, kann ich sehen, wenn der button gesetzt ist (also ich weiß, dass Sie versucht darauf zu klicken) und das Feuer, das Ereignis (das deaktivieren alles andere, so dass es abgeschlossen werden kann). Es gibt nur ein paar Schaltflächen auf dem Formular, muss dieses Verhalten, also ich denke, diese Lösung reicht für jetzt.

  • Habe gerade einen kurzen test, und das blur-Ereignis feuert immer zuerst bei mir im IE7.
  • Wirklich? Ich glaube, Sie... lassen Sie mich versuchen, ein quick-test als auch...
  • Ok, du hast Recht. Ich habe bearbeitet die Frage, denn ich habe immer noch komische Verhalten.
InformationsquelleAutor Cᴏʀʏ | 2009-07-22
Schreibe einen Kommentar