willie.de: removeAttributeNode()

Hallö ins Forum,

und ein gesundes neues (Rest-)Jahr!

Ich verzweifle gerade am removeAttributeNode(): Ich weise in einem Eingabefeld beim Eintreten eine CSS-Klasse zu, das funktioniert auch hübsch.

Beim Verlassen soll die das Attribut 'class' wieder wieder gelöscht werden. Das können nur meine Geckos. M$IE und Opera verweigern den Dienst ohne irgendwelche Fehlermeldungen :-(

Ich hab hier den Code aufs Wesentliche gekürzt:

<html>
<head>
<style type="text/css">
<!--
.new { background:green; color:white; border:solid yellow thin; }
//-->
</style>
<script type="text/javascript">
<!--
function add_class(name) {
var css_class = document.createAttribute("class");
css_class.nodeValue = "new";
name.setAttributeNode(css_class);
}
function rem_class(name) {
name.removeAttributeNode(name.getAttributeNode("class"));  // das funxt net :-(
}
//-->
</script>
</head>

<body>
<form>
<input id="eins" value="blabla" onfocus="add_class(this);" onBlur="rem_class(this);">
<input value="lalala" onfocus="add_class(this);" onBlur="rem_class(this);">
</form>
</body>
</html>

Wenn ich die JS-Funktion auf andere Elemente anwende, bekomme ich das gleiche Verhalten der Browser (FF, NS tun es - OP, IE nicht), ebenso wenn ich die Notierung wie hier angegeben verwende.

Kann mir jemand auf die Sprünge helfen, wo mein Fehler liegt?

Danke für Unterstützung und
Grüße aus Leipzig
willie

--
sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:} va:} de:> zu:} fl:( ss:| ls:# js:|
Selfcode Decoder
  1. Hallö nochmal,

    hab meinen Fehler gerade beim Verlinken entdeckt: "Internet Explorer ... interpretieren diese Methode nicht. Opera ... hat aber offenbar Probleme ..." Ok. Is ja nichts Neues :-(

    Also weiter am Problem. Obwohl mir das Node-Modell halbwegs klar ist: wieso funktioniert dann

    function rem_class(name) {
    name.removeAttribute("class");
    }

    nicht?

    Danke für Unterstützung und
    Grüße aus Leipzig
    willie

    --
    sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:} va:} de:> zu:} fl:( ss:| ls:# js:|
    Selfcode Decoder
    1. Hallö ins Forum,

      auch wenn das angesichts des Nebenstranges um die Sinnhaftigkeit leerer Klassen scheinbar an Relevanz verloren hat - das ist nur scheinbar so. Ich hätte hier auch gern noch ne Kopfwäsche ;-)

      Obwohl mir das Node-Modell halbwegs klar ist: wieso funktioniert dann

      function rem_class(name) {
      name.removeAttribute("class");
      }

      nicht

      Wie gehabt, die Geckos machens, M$IE und Opera nicht. Zur Navigationsvermeidung: es ging um so ein Beispiel:
         <input onfocus="add_class(this);" onBlur="rem_class(this);">

      Mit großem Danke für eure Mühe und
      Grüßen aus Leipzig
      willie

      --
      sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:} va:} de:> zu:} fl:( ss:| ls:# js:|
      Selfcode Decoder
      1. Hallo,

        Obwohl mir das Node-Modell halbwegs klar ist: wieso funktioniert dann

        function rem_class(name) {
        name.removeAttribute("class");
        }

        nicht
        Wie gehabt, die Geckos machens, M$IE und Opera nicht.

        Welcher Opera?

        Der IE machts nicht, weil er den Attributknoten "class" per default als leeren Attributknoten mitführt. Dieser lässt sich hier nicht löschen.

        Beispiel:

        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
                "http://www.w3.org/TR/html4/strict.dtd">
        <html>
        <head>
        <title>Titel</title>
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
        <style type="text/css">
        <!--
        .test {background-color:red;}
        -->
        </style>
        <script type="text/javascript">
        <!--
        function add_class(name) {
         try {
          //IE hat hier bereits einen leeren Attributknoten "class".
          var myClassAttr = name.getAttributeNode("class");
          alert(myClassAttr.name + ":" + myClassAttr.value);
          name.focus();
         } catch (e) {
           //Geckos und Opera 8.5 haben diesen leeren Attributknoten "class" nicht.
           alert(e);
           name.focus();
         }

        var myClassAttr = document.createAttribute("class");
         myClassAttr.value = "test"
         name.setAttributeNode(myClassAttr);
        }

        function rem_class(name) {
         var myClassAttr = name.getAttributeNode("class");
         alert(myClassAttr.name + ":" + myClassAttr.value);
         name.removeAttributeNode(myClassAttr);

        try {
          //IE hat hier immer noch einen leeren Attributknoten "class".
          myClassAttr = name.getAttributeNode("class");
          alert(myClassAttr.name + ":" + myClassAttr.value);
         } catch (e) {
           //Geckos und Opera 8.5 haben hier keinen Attributknoten "class" mehr.
           alert(e);
         }
        }
        //-->
        </script>
        </head>
        <body>
        <p><input onfocus="add_class(this);" onBlur="rem_class(this);"></p>
        </body>
        </html>

        viele Grüße

        Axel

        1. Hallö nochmal,

          Welcher Opera?

          Der 7.23, bin wohl bissel hinterher... Meldet (gekürzt):
          name: TypeError
          message: Statement on line 7: Expression evaluated to null or undefined and is not convertible to Object: myClassAttr
          Backtrace:
            Line 7 of inline#1 script
              alert(myClassAttr.name + ":" + myClassAttr.value);
            In unknown script
              add_class(this);
            At unknown location
              {event handler trampoline}

          Der IE machts nicht, weil er den Attributknoten "class" per default als leeren Attributknoten mitführt. Dieser lässt sich hier nicht löschen.

          Danke für Aufklärung!

          Grüße aus Leipzig
          willie

          --
          sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:} va:} de:> zu:} fl:( ss:| ls:# js:|
          Selfcode Decoder
  2. Hallo,

    Ich hab hier den Code aufs Wesentliche gekürzt:

    <html>
    <head>
    <style type="text/css">
    <!--
    .new { background:green; color:white; border:solid yellow thin; }
    //-->
    </style>

    <script type="text/javascript">
    <!--
    function add_class(name) {
    name.className="new";
    }
    function rem_class(name) {
    name.className="";
    }
    //-->
    </script>

    </head>

    <body>
    <form>
    <input id="eins" value="blabla" onfocus="add_class(this);" onBlur="rem_class(this);">
    <input value="lalala" onfocus="add_class(this);" onBlur="rem_class(this);">
    </form>
    </body>
    </html>

    Kann mir jemand auf die Sprünge helfen, wo mein Fehler liegt?

    Du siehst DOM zu kompliziert.

    Die Eigenschaft "className" wird nicht nur als Eigenschaft von document.all, sondern allgemein von HTMLElements unterstützt.

    viele Grüße

    Axel

    1. Hallö, Axel Richter,

      Du siehst DOM zu kompliziert.

      Kann wohl sein.

      Die Eigenschaft "className" wird nicht nur als Eigenschaft von document.all, sondern allgemein von HTMLElements unterstützt.

      Das löst mein Problem nur teilweise. Auch auf kompliziertem Weg kann ich dem Element eine andere Klasse zuweisen (bzw. einen anderen Namen vergeben). Ich möchte sie aber - aus rein formalen Gründen - wieder löschen.

      Grüße aus Leipzig
      willie

      --
      sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:} va:} de:> zu:} fl:( ss:| ls:# js:|
      Selfcode Decoder
      1. Hallo,

        Auch auf kompliziertem Weg kann ich dem Element eine andere Klasse zuweisen (bzw. einen anderen Namen vergeben). Ich möchte sie aber - aus rein formalen Gründen - wieder löschen.

        Kann man die formalen Gründe erfahren? Die JavaScript-Eigenschaft [HTMLElement].className existiert immer, egal, ob ein Attribut "class" gesetzt ist oder nicht. Was willst Du also mit dem Entfernen des Attributs erreichen?

        viele Grüße

        Axel

        1. Hallö nochmal,

          Kann man die formalen Gründe erfahren?

          Kurz: Die Elemente haben im reinen HTML kein class-Attribut. Und deswegen möchte ich es einfach wieder löschen.
          Ausführlich: Ein ähnliches Script verwende ich woanders zum Verbergen bzw. Anzeigen geamter <div>'s, und das soll beim Klicken auf ein bestimmtes Element innerhalb des Containers geschehen, welches überdies noch verändert wird. Daher der Zugriff über 'node'.

          Was willst Du also mit dem Entfernen des Attributs erreichen?

          Dass ich nicht von Anfang an eine Klasse vergeben bzw. die gleiche Klasse wie "normal" noch extra definieren muss. Ist tatsächlich eher ne Formfrage (schöner Code und so was ;-). Allerdings hab ich den Eindruck, dass mein Lieblingsbrauser NN4 beim Verwenden von CSS weniger Mist baut, wenn keine Klassen oder gar Styles in den Elementen gesetzt sind.

          Grüße aus Leipzig
          willie

          --
          sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:} va:} de:> zu:} fl:( ss:| ls:# js:|
          Selfcode Decoder
          1. Kann man die formalen Gründe erfahren?
            Kurz: Die Elemente haben im reinen HTML kein class-Attribut. Und deswegen möchte ich es einfach wieder löschen.

            Glaubst du, ist aber nicht so:

            var x = document.createElement('div');  
            var attr = 'Attribute:';  
            for(var i in x) attr += '\n'+i;  
            document.write('<pre>'+ attr + '</pre>');
            

            Was willst Du also mit dem Entfernen des Attributs erreichen?
            Dass ich nicht von Anfang an eine Klasse vergeben bzw. die gleiche Klasse wie "normal" noch extra definieren muss. Ist tatsächlich eher ne Formfrage (schöner Code und so was ;-). Allerdings hab ich den Eindruck, dass mein Lieblingsbrauser NN4 beim Verwenden von CSS weniger Mist baut, wenn keine Klassen oder gar Styles in den Elementen gesetzt sind.

            Neine, das entfernen eines Standardmäßig vorhandenen Attribut ist sicher nicht sauberer, als ihm einfach einen Leerstring zu zuweisen.

            Struppi.

            1. Hallö, Struppi,

              danke für deine Zustimmung!

              Neine, das entfernen eines Standardmäßig vorhandenen Attribut ist sicher nicht sauberer, als ihm einfach einen Leerstring zu zuweisen.

              Ich möchte _kein_ standardmäßig vorhandenes HTML-Attribut im Element haben. Wenn das mit JavaScript ausgelesen (und geändert) werden kann, ist das eben JavaScript.

              Grüße aus Leipzig
              willie

              --
              sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:} va:} de:> zu:} fl:( ss:| ls:# js:|
              Selfcode Decoder
              1. Hallö nochmal, Struppi,

                du hast natürlich recht. (Ich bin grad in Eile und hatte mal wieder vorschnell gepostet.) Wenn ich mit JavaScript ne Klasse einfüge, kann ich die damit auch leer setzen.

                Entschuldigung & Danke für Unterstützung
                willie

                --
                sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:} va:} de:> zu:} fl:( ss:| ls:# js:|
                Selfcode Decoder