Mittels JavaScript "Klassen" eigene Buttons animieren

Ortwin1st

Mitglied
Hi,

bin seit einiger Zeit am tüfteln einer hübschen Lösung um Buttons zu animieren. Ich möchte das alles mit Objekten lösen, damit ich beliebig viele Buttons erzeugen kann und diese unabhängig voneinander animiert werden können. Das ist so aufgebaut, dass irgendwo im HTML Dokument ein Button mittels Div platziert ist.

Das sieht so aus:
HTML:
<div id="lnkMain2" class="link80">
<h2><a href="projekte.html" 
    onmouseover="works.startAniOver(works)" onmouseout="works.startAniOut(works)" >Projekte</a></h2>
</div>
...
<script type="text/javascript">
    // Buttons initialisieren
    works = new CButton("lnkMain2",0);
</script>

Wichtig im o.g. Code ist eigentlich nur die ID und das Erzeugen des Objekts.

Die Klasse sieht im Detail so aus:
PHP:
function CButton(id, type) 
{
    this.div = document.getElementById(id); // Beschriftung
    this.divBg = 0;
    this.divBgH = 0;
    
    this.id = id;
    this.type = type;
    this.left = this.div.offsetLeft;
    this.top = this.div.offsetTop;
    this.width = 135;
    this.height = 21;
    this.zInd = 76;
    this.opac = 0;
    
    this.idOver = 0; // ID für Interval
    
    // Button Bg erzeugen (Initialisierung)
    this.drwDiv("Bg");
}

CButton.prototype.drwDiv = function (type) 
{
    var newDiv = 0;

    // Button Caption
    /* Elegante Lösung, jedoch unbrauchbar da 1. Probleme bei der Auf-
       findung des eigenen Objekts und 2. nicht für alle Browser geeignet
    *//*   
        this.div.addEventListener('mouseover',this.startAniOver,false); // FF
        this.div.addEventListener('mouseout',this.startAniOut,false); // FF
        this.div.attachEvent('onmouseover',this.startAniOver); // IE
        this.div.attachEvent('onmouseout',this.startAniOut); // IE
    */

    // Button Bg
    newDiv = document.createElement("div");
    newDiv.id = this.id+"Bg";
    newDiv.className = "cmdBg";
    document.body.appendChild(newDiv);
    this.divBg = document.getElementById(this.id+"Bg"); // Hintergrund

    this.divBg.style.left =       this.left + "px";
    this.divBg.style.top =        this.top + "px";
    this.divBg.style.width =      this.width + "px";
    this.divBg.style.height =     this.height + "px";
    this.divBg.style.zIndex =     --this.zInd;
    
    // Button Bg Highlight
    newDiv = document.createElement("div");
    newDiv.id = this.id+"BgH";
    newDiv.className = "cmdBgH";
    document.body.appendChild(newDiv);
    this.divBgH = document.getElementById(this.id+"BgH"); // Hintergrund

    this.divBgH.style.left =       this.left + "px";
    this.divBgH.style.top =        this.top + "px";
    this.divBgH.style.width =      this.width + "px";
    this.divBgH.style.height =     this.height + "px";
    this.divBgH.style.zIndex =     --this.zInd;
    
    return 1;
}

CButton.prototype.startAniOver = function (src) 
{
    src.divBgH.style.zIndex++;
    src.opac=0;
    src.idOver = window.setInterval("aniOver('"+src+"')", 400);
}

//CButton.prototype.aniOver = function (src) 
function aniOver(src) 
{
        stat.innerHTML+="<br>"+src.id;
    if(src.opac < 100)
    {
        src.divBgH.style.opacity = src.opac/100;
        src.opac += 5;
    }
    else
    {
        window.clearInterval(src.idOver);
        src.idOver=0;
    }
}

CButton.prototype.startAniOut = function (src) 
{
    src.divBgH.style.zIndex--;
}

In der Funktion drwDiv() des Objekts erzeuge ich zu beginn 2 zusätzliche Div's, die genau unter meinem 'transparenten' Button liegen. An unterer Stelle den Highlighthintergrund und an unterster Stelle den Standardhintergrund des Buttons.

Der Highlighthintergrund soll dann beim mouseover eine Ebene nach oben verschoben werden und dort mittels setInterval und opacity kontinuierlich gefadet werden.

Nun habe ich aber schon die ganze Zeit Probleme mit dem Zugriff auf das eigene Objekt. Die Funktion aniOver(src) darf wohl nicht im Objekt stehen, wenn ich es mit setInterval() aufrufen möchte. Habe das bereits bei startAniOver(src) umgangen, indem ich die Referenz auf das Objekt als Argument mitgebe. (Hoffe ich bringe da nicht zuviel mit Java durcheinander :-( )

Wie kann man den Zugriff regeln bzw. das Problem insgesamt vernünftig lösen?
 
Zuletzt bearbeitet:
Hi Ortwin1st,

mal abgesehen davon, dass noch ein paar andere Dinge in deinem JS nicht so ganz passen ;), ändere einfach mal deinen Funktionsaufruf innerhalb des setInterval so, dass folgende Zeile daraus wird.
Javascript:
src.idOver = window.setInterval(function() { aniOver(src) }, 400);

Hoffe das hilft dir ein wenig weiter ;).

Gruß
K.
 
Zuletzt bearbeitet von einem Moderator:
Danke, funktioniert super.
Hab immer nach einer guten Referenz für JavaScript gesucht bzgl. Objekten, aber da hört's bei SelfHTML auf.

Wieso muss man das überhaupt in einen Funktionsrahmen packen?

mal abgesehen davon, dass noch ein paar andere Dinge in deinem JS nicht so ganz passen ;)

Was wäre das? Was ist da noch verbesserungsbedürftig? Soweit läuft das ja, zumindest im FF.
 
Hi,

so genau kann ich dir das auch nicht sagen. Warscheinlich wird intern der String einfach mit eval() ausgewertet. Das Problem bei setInterval ist, dass du einen String übergibst. Wenn du versuchst mittels Stringverkettung Parameter zu übergeben, also sowas "aniOver('"+src+"')", wird das nicht gehen, weils eben ein String ist und auch bleibt ;). Wenn's auf diese Weise gemacht werden soll, könnte man anstatt des Objektes auch nur die ID mitgeben "aniOver('"+src.id+"')". Der Nachteil daran ist, in aniOver müsste dann jedes mal über die übergebene ID das Objekt ausfindig gemacht werden.
Und um das ganze komplett zu machen, der FF versteht auch die folgende Syntax ;).
Javascript:
src.idOver = window.setInterval(aniOver, 400, src);
In dem Fall werden alle Parameter nach dem Intervall, einfach an die Funktion übergeben.

Gruß
K.
 
Zuletzt bearbeitet von einem Moderator:
Und um das ganze komplett zu machen, der FF versteht auch die folgende Syntax ;).
Javascript:
src.idOver = window.setInterval(aniOver, 400, src);
Das hört sich so an, als würde NUR ausschließlich der FF die Syntax verstehen. Vom IE brauche ich das ja sowieso nicht zu erwarten. ;)

Nach ein bischen googeln* bin ich jetzt auch auf diese Seite gestoßen, die sich mit dem selben Problem beschäftigt.
Es ist nicht leicht zu verstehen, aber irgendwas müssen sich doch die Entwickler von JavaScript gedacht haben.

EDIT:
Hier ist der Sachverhalt mit setTimeout() und setInterval() auch sehr schön erklärt.
Ich glaube das muss man einfach so akzeptieren, dass das so ist.

*googeln ist eine Kunst für sich ;)
 
Zuletzt bearbeitet von einem Moderator:
Zurück