Wolfgang Schlaupitz: JS+CSS-Problem bei der Darstellung von Elementen

Es soll ein <div>-Bereich ein- und ausgeblendet werden.

JS:
function changeVisibility(id) {
 if (document.getElementById) {
  if (document.getElementById(id).style.display == "none") {
   document.getElementById(id).style.display = "block";
  } else {
   document.getElementById(id).style.display = "none";
  }
 }
}

XHTML:
...
<div class="blubb">
<a href="#" onclick="changeVisibility('id');">
...
</a>
<div style="display: none" class="bla" id="id_a">
...
</div>
</div>
...

Dies funktioniert so auch ganz wunderbar!

Jetzt kommt das Problem:
Ich möchte die CSS-Angabe >>style="display: none"<< in eine externe CSS-Datei auslagern.
.bla {
display: none;
}

Dabei entsteht folgendes Problem:
Wird die XHTML-Datei aufgerufen reagiert das "Ein- und Ausblenden" erst auf den zweiten Klick bzw. Doppelklick und dies ist super unschön.

Für Hilfe wäre sehr dankbar.

Gruss

Wolfgang

  1. Hallo Wolfgang,

    Dabei entsteht folgendes Problem:
    Wird die XHTML-Datei aufgerufen reagiert das "Ein- und Ausblenden" erst auf den zweiten Klick bzw. Doppelklick und dies ist super unschön.

    Mich wunder, dass es überhaupt funktioniert. Laut deinem Code greifst du mit changeVisibility('id'); auf ein Objekt mit der ID 'id' zu, das entsprechende Element hat aber die ID 'id_a'.

    Grüße

    Marc Reichelt || http://www.marcreichelt.de/

    --
    Linux is like a wigwam - no windows, no gates and an Apache inside!
    Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
    1. Sorry
      Forum-Einstellfehler :-)
      So ist es nun korrekt:

      XHTML:
      ...
      <div class="blubb">
      <a href="#" onclick="changeVisibility('id_a');">
      ...
      </a>
      <div style="display: none" class="bla" id="id_a">
      ...
      </div>
      </div>
      ...

      Gruss

      Wolfgang

      Hallo Wolfgang,

      Dabei entsteht folgendes Problem:
      Wird die XHTML-Datei aufgerufen reagiert das "Ein- und Ausblenden" erst auf den zweiten Klick bzw. Doppelklick und dies ist super unschön.

      Mich wunder, dass es überhaupt funktioniert. Laut deinem Code greifst du mit changeVisibility('id'); auf ein Objekt mit der ID 'id' zu, das entsprechende Element hat aber die ID 'id_a'.

      Grüße

      Marc Reichelt || http://www.marcreichelt.de/

      1. Hallo Wolfgang,

        ach so ist das. :-)
        Einen habe ich aber noch:

        XHTML:
        ...
        <div class="blubb">
        <a href="#" onclick="changeVisibility('id_a');">
        ...
        </a>
        <div style="display: none" class="bla" id="id_a">
        ...
        </div>
        </div>
        ...

        Wenn jemand auf den Link klickt, wird die Seite "#" aufgerufen. Das ist das aktuelle Dokument. Das JavaScript wird also ausgeführt, hat aber keine Wirkung, weil du ja dokument.html# lädst. Wenn dokument.html# aber bereits geladen ist, wird bei allen weiteren Klicks das Dokument nicht erneut geladen - die JavaScript-Aktion ist zu sehen.
        Ändere
        <a href="#" onclick="changeVisibility('id_a');">
        also einfach in
        <a href="#" onclick="changeVisibility('id_a'); return false;">
        um.

        Grüße

        Marc Reichelt || http://www.marcreichelt.de/

        --
        Linux is like a wigwam - no windows, no gates and an Apache inside!
        Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
        1. Hallo Wolfgang,

          Ich kann mir auch nicht erklären, woran es liegt, vermute aber, das die Eigenschaft document.getElementById(id).style.display vor dem ersten Klick nicht gesetzt ist.

          Ich kann Dir nur eine andere funktionierende Alternative anbieten:

            
          document.getElementById(id).style.display = "none";  
          var sichtbar=false;  
            
          function changeVisibility(id)  
          {  
           if (document.getElementById) {  
            if (sichtbar) {  
             document.getElementById(id).style.display = "none";  
             sichtbar=false;  
            } else {  
             document.getElementById(id).style.display = "block";  
             sichtbar=true;  
            }  
           }  
          }
          

          beachte, das, wenn du die erste Zeile weglässt, wieder das selbe Problem auftaucht, seltsam...

          Gruß, Nils

          1. Vielen Dank Nils und Marco!

            so funktioniert es!

            Was ich nicht verstehe ist, dass wenn ich den style direkt in HTML-Dokument angebe - kein Problem mit der ersten Version...

            hmpf...

            Grüsse

            Wolfgang

            1. Hallo,

              Was ich nicht verstehe ist, dass wenn ich den style direkt in HTML-Dokument angebe - kein Problem mit der ersten Version...

              hmpf...

              Ja, denn JavaScript hat via DOM mit [Element].style nur Zugriff auf das Style-Objekt des Elements im Dokument. Die Angaben, welche Du suchst, kommen aber aus Style-Sheets, die nicht direkt im Dokument beschrieben werden, sondern in einem eigenen STYLE-Element oder einem externen StyleSheet. Was Du erreichen willst, ist auf alle CSS-Eigenschaften zuzugreifen, die zu sehen (im View) sind. Das geht wie hier beschrieben.

              viele Grüße

              Axel

          2. hi,

            Ich kann mir auch nicht erklären, woran es liegt, vermute aber, das die Eigenschaft document.getElementById(id).style.display vor dem ersten Klick nicht gesetzt ist.

            Natürlich ist sie das nicht - das wurde hier auch schon x-fach erklärt.

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
  2. Hello out there!

    function changeVisibility(id) {
    if (document.getElementById) {
      if (document.getElementById(id).style.display == "none") {
       document.getElementById(id).style.display = "block";
      } else {
       document.getElementById(id).style.display = "none";
      }
    }
    }

    Du suchst unnötig oft über das DOM immer wieder dasselbe Element. Effizienter ist das Script, wenn du dir das Objekt in einer Variablen merkst:

    function changeVisibility(id) {  
      var el = document.getElementById(id);  
      if (el) {  
        if (el.style.display == "none")  
          el.style.display = "block";  
        else  
          el.style.display = "none";  
      }  
    }
    

    Wenn du nur die Anzeige eines Elements ändern willst, kommt die Zuweisung an die Variable el außerhalb der Funktion. Dann bietet es sich auch an, sich den Status zu merken; das macht die Abfrage einfacher:

    var el = document.getElementById(id);  
    var visible = false;  
      
    function changeVisibility() {  
      if (el) {  
        if (visible)  
          el.style.display = "none";  
        else  
          el.style.display = "block";  
        visible = !visible;  
      }  
    }
    

    oder kürzer:

    var el = document.getElementById(id);  
    var visible = false;  
      
    function changeVisibility() {  
      if (el) {  
        el.style.display = (visible ? "none" : "block");  
        visible = !visible;  
      }  
    }
    

    <a href="#" onclick="changeVisibility('id');">

    Warum ein Anker, der zu keinem sinnvollen Ziel führt? Du willst keine andere Ressource verlinken, sondern eine Aktion auf einer Seite ausführen, dafür sind Buttons besser:

    <button onclick="changeVisibility('id_a');"> ... </button>

    Ich möchte die CSS-Angabe >>style="display: none"<< in eine externe CSS-Datei auslagern.
    .bla {
    display: none;
    }

    Dann möchtest du also in deiner Funktion auch nicht die display-Eigenschaft des Elements ändern, sondern die Klassenzugehörigkeit:

    el.className = "bla";;

    bzw.

    el.className = "";;

    Und wenn du das JavaScript auch noch auslagern willst:

    <button id="changeVisibility"> ... </button>

    window.onload = function() {  
      document.getElementById("changeVisibility").onclick = function() {  
        changeVisibility();  
      };  
    };
    

    See ya up the road,
    Gunnar

    --
    “Remember, in the end, nobody wins unless everybody wins.” (Bruce Springsteen)
    1. Hallo,

      document.getElementById("changeVisibility").onclick = function() {

      changeVisibility();
      };

        
      `document.getElementById("changeVisibility").onclick = changeVisibility;`{:.language-javascript}  
        
      reicht in dem Fall, eine umhüllende Funktion ist nicht nötig.  
        
      Im Übrigen sollte man keine Funktion und einem Element denselben Namen/ID geben - im IE kann man auf ein Element mit der ID changeVisibility über die globale Variable changeVisibility zugreifen. Wenn es zudem noch eine gleichnamige Funktion gibt, sind Konflikte vorprogrammiert.  
        
      Mathias
      
      -- 
      [Visitenkarte](http://community.de.selfhtml.org/visitenkarten/view.php?key=17) · [SELFHTML Weblog](http://aktuell.de.selfhtml.org/weblog/)