Unzuverlässiges Bilderaustauschen
beza1e1
- javascript
Hi,
ich arbeite an einer eCommerce-Seite. Neben den Produkten ist ein button mit einem Bild drin. Wenn der Besucher da drauf klickt, soll das Bild ausgetauscht werden, so dass eine animierte Sanduhr zu sehen ist und außerdem soll verhindert werden, dass der Knopf mehrmals angeklickt wird und das Produkt damit mehrmals im Warenkorb landet.
Das Javascript dazu sieht bisher so aus:
function buttonsent(button) {
var img = button.firstChild;
var oldname = img.src;
var i = oldname.length - 4;
img.src = oldname.substring(0,i) + "_sent.gif";
// prevent further clicks and form sending
button.disabled = true;
button.onclick = null;
// but send form this time!
parent = button.parentNode;
while (parent.tagName.toLowerCase() != "form") {
parent = parent.parentNode;
}
parent.submit();
/* disable form */
parent.action = null;
/* Reassigning the img.src should keep it animated
* see http://elliottback.com/wp/animated-gif-stops-javascript-click/ */
img.src = img.src;
}
Und das HTML
<button onclick="setLocation('...')" onmousedown="buttonsent(this);">
<img src="/images/warenkorb/warenkorb_button.png" alt="bestellen" />
</button>
Das onclick script ist vom Shopsystem (Magento) und sollte vermutlich drin bleiben.
Das Problem ist nun, dass das script nicht immer funktioniert. Ich habe keine Ahnung woran diese Unzuverlässigkeit liegt.
Hi,
Das Problem ist nun, dass das script nicht immer funktioniert.
neben dem offensichtlichen Fehler, dass button.firstChild in dem von Dir gezeigten Code nicht dem <img>-Element entspricht: "Funktioniert nicht" funktioniert nicht. Fehlerbeschreibung, bitte.
Cheatah
function buttonsent(button) {
var img = button.firstChild;
Das liefert je nach Browser den Textknoten, nicht das img-Element. Verwende besser button.getElementsByTagName("img")[0] oder entferne Leerzeichen und Zeilenumbrüche zwischen den Tags.
button.onclick = null;
Wieso setzt du dann ein onclick-Attribut?
// but send form this time!
parent = button.parentNode;
while (parent.tagName.toLowerCase() != "form") {
parent = parent.parentNode;
}
Das ist unnötig - ein Formularfeld-Elementobjekt hat eine Eigenschaft namens form, die auf das form-Elementobjekt verweist.
button.form liefert dir bereits das Formular
parent.submit();
Das verstehe ich auch nicht, du hast einen Submit-Button in einem Formular. Wenn du nicht onclick="buttonsent(this); return false" notierst, also die [link:http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#standardaktion@title=Standardaktion unterdrückst], dann wird das Formular automatisch abgesendet. D.h. du brauchst submit() gar nicht manuell aufrufen
Wenn du es vorher beim mousedown absendest und die Action löscht, dann kann es sein, dass der Browser das von JavaScript ausgelöste Absenden unterbricht und das Formular nochmal nach null versendet. Ich weiß nicht, ob das die Fehlerursache ist, ich würde es jedenfalls nicht darauf ankommen lassen und klassisch lösen.
/* disable form */
parent.action = null;
Macht das Sinn? Welchen Zweck soll das erfüllen?
[code lang=html]
<button onclick="setLocation('...')" onmousedown="buttonsent(this);">
<img src="/images/warenkorb/warenkorb_button.png" alt="bestellen" />
</button>
> Das onclick script ist vom Shopsystem (Magento) und sollte vermutlich drin bleiben.
?? Aber du überschreibst den Handler doch? Dann kannst du es auch löschen.
Mathias
--
[JavaScript-Erweiterung für das SELFHTML-Forum](http://forum.de.selfhtml.org/js/doku/)
»» ~~~javascript
function buttonsent(button) {
»» var img = button.firstChild;
Das liefert je nach Browser den Textknoten, nicht das img-Element. Verwende besser button.getElementsByTagName("img")[0] oder entferne Leerzeichen und Zeilenumbrüche zwischen den Tags.
Ok, Danke für den Hinweis.
»» button.onclick = null;
Wieso setzt du dann ein onclick-Attribut?
Das onclick ist Vorgabe von Magento. Nachdem es einmal aufgerufen wurde, soll der Besucher durch ungeduldiges Klicken die Daten nicht mehrmals übertragen können. Als visuelles Feedback wird das Bild ausgetauscht und zusätzlich der DOM so abgeändert, dass weitere Klicks nichts bewirken.
button.form liefert dir bereits das Formular
Ok, Danke für den Hinweis.
»» parent.submit();
Das verstehe ich auch nicht, du hast einen Submit-Button in einem Formular. Wenn du nicht onclick="buttonsent(this); return false" notierst, also die [link:http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#standardaktion@title=Standardaktion unterdrückst], dann wird das Formular automatisch abgesendet. D.h. du brauchst submit() gar nicht manuell aufrufen
Wenn du es vorher beim mousedown absendest und die Action löscht, dann kann es sein, dass der Browser das von JavaScript ausgelöste Absenden unterbricht und das Formular nochmal nach null versendet. Ich weiß nicht, ob das die Fehlerursache ist, ich würde es jedenfalls nicht darauf ankommen lassen und klassisch lösen.
Das ist vermutlich recht unzuverlässiges Verhalten und ich werd es irgendwie ausbauen. Danke
»» /* disable form */
»» parent.action = null;Macht das Sinn? Welchen Zweck soll das erfüllen?
Gleiche Idee wie bereits erwähnt - der Besucher soll das Formular nicht durch ungeduldiges Klicken nochmal abschicken können.
»» [code lang=html]
»» <button onclick="setLocation('...')" onmousedown="buttonsent(this);">
»» <img src="/images/warenkorb/warenkorb_button.png" alt="bestellen" />
»» </button>
»»
> »» Das onclick script ist vom Shopsystem (Magento) und sollte vermutlich drin bleiben.
>
> ?? Aber du überschreibst den Handler doch? Dann kannst du es auch löschen.
Oh, da hatte ich nicht ganz den richtigen HTML geschrieben. buttonsent() wird in onmouseup ausgelöst. Wird es dann vor oder nach dem onclick event aufgerufen? Wer kann wen überschreiben?
Wird es dann vor oder nach dem onclick event aufgerufen? Wer kann wen überschreiben?
mousedown wird zuerst gefeuert, da zu einem vollständigen click noch ein mouseup notwendig ist. Also: mousedown, mouseup, click.
Mathias