Hallo,
control.onclick = new [link:http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Function@title=Function]("slideshow_switch(" + j + ");");
Ich find das immer noch unschön. Man sollte zu vermeiden suchen, JavaScript-Code dynamisch zu erzeugen, sei es nun eval, new Function oder setInterval/setTimeout. In der Regel verwendet man für sowas Closures, also einfach control.onclick = function () { slideshow_switch(j); };. j ist dann in der Funktion verfügbar. Hier ist das aber nicht so einfach, weil die Variable j nach der onclick-Zuweisung noch geändert wird. Gut, dafür bietet sich hier eine andere elegante Möglichkeit an: Man speichert die Nummer einfach direkt am betreffenden Element, bei dessen Event-Handler sie benötigt wird.
var control = document.createElement('img');
control.src = '/player_play.png';
control.className = 'control';
control.slideshow_number = j;
control.onclick = slideshow_switch;
function slideshow_switch (e) {
alert(this.slideshow_number);
}
Anstatt des mehrdimensionalen numerischen Arrays slideshow würde ich Object-Objekte verwenden und diese in den Array hängen:
slideshow = {
image_list : elements[i].getElementsByTagName('img'),
active_image : 1,
active : false,
interval : null
};
slideshows.push(slideshow);
slideshows[number].active ist dann lesbarer als slideshows[number][2].
Ein weiterer Schritt wäre, alles mit Closures und dem Speichern an den Elementknoten zu lösen. Das zentral-globale Speichern aller Informationen in einem mehrdimensionalen Array ist wahrscheinlich nicht nötig. Ein Beispiel:
window.onload = function () {
mod_slideshow.init();
};
function hasClass (element, className) {
var regexp = new RegExp("(^|\\s)" + className + "(\\s|$)");
return regexp.test(element.className);
}
var mod_slideshow = new Object;
mod_slideshow.interval = 3000;
mod_slideshow.init = function () {
var elements = document.getElementsByTagName('*');
for (var i = 0, element, slideshow; i < elements.length; i++) {
element = elements[i];
if (!hasClass(element, "slideshow")) {
continue;
}
slideshow = {
image_list : element.getElementsByTagName('img'),
active_image : 0,
active : false,
interval_id : null
};
var control = document.createElement('img');
control.src = '/player_play.png';
control.className = 'control';
control.slideshow = slideshow;
control.onclick = mod_slideshow.switcher;
element.appendChild(control);
}
};
mod_slideshow.switcher = function (e) {
var control = this;
var slideshow = control.slideshow;
if (slideshow.active) {
window.clearInterval(slideshow.interval_id);
control.src = '/player_play.png';
} else {
mod_slideshow.trigger(control);
control.src = '/player_pause.png';
var closure = function () { mod_slideshow.trigger(control); };
slideshow.interval_id = window.setInterval(closure, mod_slideshow.interval);
}
slideshow.active = !slideshow.active;
};
mod_slideshow.trigger = function (control) {
var slideshow = control.slideshow;
slideshow.image_list[slideshow.active_image].style.display = 'none';
slideshow.active_image++;
slideshow.active_image = slideshow.active_image % (slideshow.image_list.length - 1);
slideshow.image_list[slideshow.active_image].style.display = 'inline';
};
Der globale Array mit allen Slideshow-Informationen fällt damit weg, die jeweiligen Infos werden in einem Object an der Control gespeichert.
Wie in https://forum.selfhtml.org/?t=130522&m=843795 habe ich alle zusammenhängenden Methoden und Eigenschaften in einem Object gruppiert, der globalen Scope bleibt aufgeräumt.
Den HTML-Code könnte man natürlich im Hinblick auf Semantik optimieren, in der Regel setzt man eine ol oder ul ein. Außerdem kann man das ganze auch noch zugänglich ohne Javascript und Maus gestalten.
Mathias