Hallo,
Das besagte onunload-Event ist nicht so praktisch, denn darüber kann man das Verlassen der Seite nicht abbrechen, sondern nur lustig z.B. ein Popup-Fenster öffnen, das gerne geblockt wird.
Der onbeforeunload-Event-Handler ist geeigneter, Gecko und MSIE kennen ihn. Damit kann man ein Meldungsfenster erscheinen lassen, in dem der Anwender auf das nicht abgesendete Formular aufmerksam gemacht wird. Dort kann er dann ggf. Abbrechen wählen.
AJAX-Gefummel brauchen - wenn man nicht schon jede Feldänderung direkt an den Server senden will - somit nur Opera und Konqueror. Opera macht das recht gut. Konqueror sendet zwar den Request, wartet aber trotz synchronem Request nicht mit zum readyState 4, bevor er die Seite wechselt. Ich würde im Konqueror nicht darauf vertrauen, dass der Request immer ankommt.
Mal ein (längeres, aber trotzdem primitives) Beispiel (das Serialisieren der Formulardaten ist natürlich stümperhaft und funktioniert gerade mit dem Testformular - es geht ums Prinzip):
<html><head><title>Formular speichern</title>
<script type="text/javascript">
[code lang=javascript]function xmlhttp () {
_xmlhttp = false;
if (typeof(ActiveXObject) != "undefined") {
try {
_xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
_xmlhttp = false;
}
} else if (typeof(XMLHttpRequest) != 'undefined') {
_xmlhttp = new XMLHttpRequest();
}
return _xmlhttp;
}
function urlencode (str) {
var code = "";
for (var i = 0; i < str.length; i++) {
if (str.charAt(i) == " ") {
code += "+";
} else if (str.charAt(i) == "+") {
code += "%2B";
} else if (str.charCodeAt(i) > 127) {
code += encodeURI(str.charAt(i));
} else {
code += escape(str.charAt(i));
}
}
return code;
}
function autosave (form) {
var serialized_form = "";
for (var i = 0; i < form.elements.length; i++) {
if (form.elements[i].type == "text" && !form.elements[i].disabled) {
serialized_form += urlencode(form.elements[i].name) + "=" + urlencode(form.elements[i].value);
if (form.elements.length - i > 2)
serialized_form += "&";
}
}
var conn = xmlhttp();
if (!conn) return;
conn.open("POST", form.action, false);
conn.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
conn.onreadystatechange = function (e) {
if (this.readyState != 4)
return;
if (this.responseText == "saved") {
window.alert("Ihre Formulardaten wurden erfolgreich gespeichert.");
} else {
window.alert("Es gab einen Fehler beim Speichern der Formulardaten. Betätigen Sie bitte gleich »Zurück« und senden Sie das Formular über den Knopf »Daten speichern« ab.");
}
};
conn.send(serialized_form);
}
function beforeunload () {
if (form_changed && !form_submitted) {
unload_stopped = true;
return "Sie verlassen die Seite, ohne dass Ihre Formulareingaben gespeichert worden sind. Bitte wählen Sie »Abbrechen« und senden Sie das Formular über den Knopf »Daten speichern« ab, sonst gehen die Eingaben verloren.";
}
}
function unload () {
if (form_changed && !form_submitted && !unload_stopped) {
window.alert("Sie verlassen die Seite, ohne dass Ihre Formulareingaben gespeichert worden sind. Es wird versucht, die Daten automatisch zu speichern.");
autosave(document.forms.formular);
}
}
function load () {
document.forms.formular.elements[0].onchange = form_change;
document.forms.formular.onsubmit = form_submit;
}
function form_change () {
form_changed = true;
}
function form_submit () {
form_submitted = true;
}
var form_changed = false;
var form_submitted = false;
var unload_stopped = false;
window.onload = load;
window.onbeforeunload = beforeunload;
window.onunload = unload;
~~~</script>
</head><body>
<form action="save.php" method="post" accept-charset="utf-8" id="formular">
<p><input type="text" name="=%& +#-.,öäü" value="=%& +#-.,öäü"></p>
<p><input type="submit" value="Daten speichern"></p>
</form>
<p><a href="js-save-form.html">weg</a></p>
</body></html>[/code]
Mathias