JSON, DOM, Styles. Browserunterschiede..

versuch13

Erfahrenes Mitglied
Hi, ich will mich etwas mehr mit JavaScript beschäftigen, richtig tief in die Materie gehen, OOP etc.. (dazu hätte ich direkt auch gerne noch einen Tipp für richtig gute Lektüre, es soll auf jeden Fall sehr ausführlich sein, am besten alles ansprechen was JavaScript zu bieten hat, und das in einem guten Programmierstil, wenn möglich auf deutsch, aber ich bin für jeden Tipp dankbar, Bücher, Webseiten, Blogs, einfach alles)

Daher hab ich mich hingesetzt und das ganze angefangen in die Praxis umzusetzen.

Erst einfach mal das Script:

Code:
    Element = {
        /* Element.setStyle('element', {options}) */
        setStyle: function(e, options) {
            e.style.color = options.color;
            e.style.fontSize = options.fontSize;
            e.style.background = options.bgColor;
            e.style.padding = options.padding;
            e.style.margin = options.margin;
            e.style.display = options.display;
            e.style.fontWeight = options.fontWeight;
        },
        /* Element.toggle('element') */
        toggle: function(e) {
            if (e.style.display != 'none') {
                e.style.display = 'none';
            } else {
                e.style.display = '';
            }            
        },
        /* Element.hide('element') */
        hide: function(e) {
            if (e.style.display != 'none') {
                e.style.display = 'none';
            }
        }
    }
    
    kollabieren = function(id) {
        var toggler = document.getElementById('deflist').getElementsByTagName('dt');
        for(var i=0; i < toggler.length; i++) {
            var e = (toggler)[i];
            Element.hide(e.nextSibling.nextSibling);
            e.onclick = function() {
                for(var i=0; i < toggler.length; i++) {
                    var e = (toggler)[i];
                    Element.setStyle(e, {color: ''});
                    Element.hide(e.nextSibling.nextSibling);
                }
                Element.setStyle(this, {color: '#FF0000'});
                Element.toggle(this.nextSibling.nextSibling);
            }
        }
    }
    
    window.onload = function() {
       kollabieren();
    }
HTML:
    <dl id="deflist">
       <dt>Definition Term 1</dt>
       <dd>Description. Description. Description. Description. Description. Description. </dd>       
       <dt>Definition Term 2</dt>
       <dd>Description. Description. Description. Description. Description. Description. </dd>
       <dt>Definition Term 3</dt>
       <dd>Description. Description. Description. Description. Description. Description. </dd>
    </dl>


Bei Klick auf einen Definition Term wird die dazugehörige Description eingeblendet. Das ganze funktioniert auch bestens in Firefox & Opera, nur der IE macht nicht mit. Zu Anfang werden alle dd Elemente ausgeblendet und bei onclick auf das vorherige dt Element eingeblendet. Im IE allerdings wird von anfang an nur das erste dt und das alle dd Element angezeigt. Wäre nett wenn mir dazu jemand einen Tipp oder eine Lösung hätte.


Vielen Dank. Grüße
 
Zuletzt bearbeitet:
Hi,

die unterschiedlichen Browser interpretieren nextSibling unterschiedlich. So liefert der IE für
Code:
e.nextSibling.nextSibling
bereits das nächste DT-Element, Firefox dagegen das erwartete DD (Textknoten wird mitgezählt).

Abhilfe kannst Du schaffen, indem Du die Folgeelemente in einer while-Schleife solange prüfst, bis das nächste
DD-Element gefunden wurde.

Weiterhin musst Du bei in setStyle prüfen, ob ein gewünschter Style übergeben wurde und evtl. einen Standardwert
übergeben - sonst wird es mit einer Fehlermeldung quittiert.

Zuletzt habe ich die onclick-Funktion angepasst. Es wird nun bei jedem Aufruf ein DT-Array erstellt, durchlaufen und
die erforderlichen Schritte ausgeführt. Ich habe es weitestgehend kommentiert, hoffentlich kannst Du etwas damit anfangen.
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<head>
<title>www.tutorials.de</title>
<meta name="author" content="Quaese">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">

<script type="text/javascript">
<!--
Element = {
    /* Element.setStyle('element', {options}) */
    setStyle: function(e, options) {
        e.style.color = (typeof(options.color) == "undefined")?"":options.color;
        e.style.fontSize = (typeof(options.fontSize) == "undefined")?"":options.fontSize;
        e.style.background = (typeof(options.bgColor) == "undefined")?"":options.bgColor;
        e.style.padding = (typeof(options.padding) == "undefined")?"":options.padding;
        e.style.margin = (typeof(options.margin) == "undefined")?"":options.margin;
        e.style.display = (typeof(options.display) == "undefined")?"":options.display;
        e.style.fontWeight = (typeof(options.fontWeight) == "undefined")?"":options.fontWeight;
    },
    /* Element.toggle('element') */
    toggle: function(e) {
        if (e.style.display != 'none') {
            e.style.display = 'none';
        } else {
            e.style.display = '';
        }
    },
    /* Element.hide('element') */
    hide: function(e) {
        if (e.style.display != 'none') {
            e.style.display = 'none';
        }
    }
}

kollabieren = function(id) {
    var toggler = document.getElementById('deflist').getElementsByTagName('dt');
    for(var i=0; i < toggler.length; i++) {
        var e = toggler[i];
        var objDD = e.nextSibling;
        // Zugehörige Definitionsbeschreibung ermitteln
        while(objDD.nodeName.toUpperCase() != "DD"){
          objDD = objDD.nextSibling;
        }

        // Beschreibung verstecken
        Element.hide(objDD);

        // Onclick-Event mit Funktion versehen
        e.onclick = function() {
            // Array mit allen Defintionstermen holen
            var arrToggler = document.getElementById('deflist').getElementsByTagName('dt');

            // Alle Terme durchlaufen -> zunächst alle verstecken (außer auslösenden Toggler)
            for(var i=0; i<arrToggler.length; i++) {
              var objToggler = arrToggler[i];

              // Falls es sich nicht um das auslösende Element handelt
              if(objToggler != this){

                // Zugehörige Beschreibung ermitteln
                var objDD = objToggler.nextSibling;
                while(objDD.nodeName.toUpperCase() != "DD"){
                  objDD = objDD.nextSibling;
                }

                Element.setStyle(objToggler, {color: ''});
                Element.hide(objDD);
              }
            }

            Element.setStyle(this, {color: '#FF0000'});

            // Beschreibung zum aktuellen Term ermitteln
            var objDD = this.nextSibling;
            while(objDD.nodeName.toUpperCase() != "DD"){
              objDD = objDD.nextSibling;
            }

            // Element einblenden
            Element.toggle(objDD);
        }
    }
}

window.onload = function() {
   kollabieren();
}
//-->
</script>
</head>
<body>
    <dl id="deflist">
       <dt>Definition Term 1</dt>
       <dd>Description. Description. Description. Description. Description. Description. </dd>
       <dt>Definition Term 2</dt>
       <dd>Description. Description. Description. Description. Description. Description. </dd>
       <dt>Definition Term 3</dt>
       <dd>Description. Description. Description. Description. Description. Description. </dd>
    </dl>
</body>
</html>
Ciao
Quaese
 
Vielen Dank! Nur nochmal um zu prüfen ob ich dass jetzt richtig verstehe:


Code:
        var e = toggler[i];
        var objDD = e.nextSibling;
        // Zugehörige Definitionsbeschreibung ermitteln
        while(objDD.nodeName.toUpperCase() != "DD"){
          objDD = objDD.nextSibling;
        }


var objDD, ist der Inhalt der dt - Elemente falls richtig interpretiert (also Firefox & Co), der
IE jedoch liefert hier schon das darauf folgende dd - Element, dass liefert er mir jedenfalls per alert(). Nur die while Schleife verstehe ich jetzt nicht so ganz, klar ist dass du darin objDD wieder überschreibst (und auf next.Sibling zugreifst, was ja dann meinem e.nextSibling.nextSibling entspricht) und so auch im Firefox das nächste dd - Element erhalten wird.
Wird die Schleife von IE gar nicht durchlaufen?- denn er gibt mir kein alert() zurück? Weshalb das toUpperCase()? Im Prinzip überprüfst du also, ob der Element name von objDD ungleich dd ist, in Firefox entspricht objDD == #text, daher durchläuft er die Schleife, IE durchläuft die Schleife nicht weil objDD == dd ist, aber wozu das toUpperCase()?

Und in der onclick Funktion, erstellst du ein neues array arrToggler, kann ich da nicht auf das array toggler zugreifen?


Danke. Gruß
 
Hi,

Zur while-Schleife:
Die Schleife hat lediglich den Sinn, das erste DD-Element von einem Startknoten ausgehend zu ermitteln und
somit für jeden Browser zu gewährleisten, dass gleiche Element zu bearbeiten. Bei Deiner HTML-Struktur wird
sie in der Tat vom IE nicht durchlaufen.

Zu toUpperCase:
Das toUpperCase ist nur zur Sicherheit eingebaut. Somit stelle ich sicher, dass der Elementname immer in
Grossbuchstaben vorliegt und kann entsprechend vergleichen.

Zu arrToggler:
Die onclick-Funktion wird immer aufgerufen, wenn der entsprechende Event eingetreten ist. Zu diesem
Zeitpunkt ist die Funktion kollabieren jedoch abgearbeitet und das Array steht somit nicht mehr zur Verfügung.
Aus diesem Grund wird die DT-Kollektion erneut erstellt.
Eine Alternative wäre es, das Array global zu erstellen und dann darauf zuzugreifen.

Ich hoffe Deine Fragen damit alle beantwortet zu haben.

Ciao
Quaese
 
Ja, bestens, alles verstanden. Nur nochmal zum zweiten array, wenn ich dass nicht erstelle und auf das erste zugreife, funktioniert es doch aber trotzdem:

Code:
kollabieren = function(id) {
    var toggler = document.getElementById('deflist').getElementsByTagName('dt');
    for(var i=0; i < toggler.length; i++) {
        var e = toggler[i];
        var objDD = e.nextSibling;
        
        // Zugehörige Definitionsbeschreibung ermitteln
        while(objDD.nodeName.toUpperCase() != "DD"){
          objDD = objDD.nextSibling;          
        }

        // Beschreibung verstecken
        Element.hide(objDD);

        // Onclick-Event mit Funktion versehen
        e.onclick = function() {

            // Alle Terme durchlaufen -> zunächst alle verstecken (außer auslösenden Toggler)
            for(var i=0; i<toggler.length; i++) {
              var objToggler = toggler[i];

              // Falls es sich nicht um das auslösende Element handelt
              if(objToggler != this){

                // Zugehörige Beschreibung ermitteln
                var objDD = objToggler.nextSibling;
                while(objDD.nodeName.toUpperCase() != "DD"){
                  objDD = objDD.nextSibling;
                }

                Element.setStyle(objToggler, {color: ''});
                Element.hide(objDD);
              }
            }

            Element.setStyle(this, {color: '#FF0000'});

            // Beschreibung zum aktuellen Term ermitteln
            var objDD = this.nextSibling;
            while(objDD.nodeName.toUpperCase() != "DD"){
              objDD = objDD.nextSibling;
            }

            // Element einblenden
            Element.toggle(objDD);
        }
    }
}

Also, bei mir läuft es jedenfalls. Sollte das nicht so sein?


Außerdem verweise ich grad nochmal auf den ersten Absatz in meinem ersten Post bezüglich der Lektüre, vielleicht hat da jemand einen guten Buch Tipp für mich?


Danke.
 

Neue Beiträge

Zurück