invrecon: Button mit JavaScript dynamisch einfügen

Hi Leute
Ich benutze Greasemonkey und würde damit gerne auf einer Webseite einen Button einfügen. Das wäre an sich noch kein Problem. Ich mache mit

var myButton = document.createElement("button");

einfach einen neuen Button und hänge ihn mit

document.getElementById("meinDiv").appendChild(myButton);

einfach an dem auf der Webseite bereits vorhandenen div "meinDiv" ein.
Soweit so gut. Nun würde ich aber dem Button gerne noch einige Attribute zuweisen wie zum Beispiel den value oder das onClick()-Ereignis. Ich habe ziemlich lange gesucht und herausgefunden, dass man gewisse Eigenschaften eines Buttons auf diese Weise ändern kann:
myButton.setAttribute('id', 'neuerButton');

Allerdings muss man, um den Text auf dem Button zu ändern, zuerst einen Textknoten erstellen und ihn dann an den Button hängen:

var buttontext = document.createTextNode('Schriftart ändern');  
myButton.appendChild(buttontext);

Wieso kann ich den Text auf dem Button nicht einfach so:
myButton.setAttribute('value', 'Hier klicken!');
oder so:
myButton.value = "Hier klicken!";
ändern?

Würde mich über Antworten freuen!
Gruss
invrecon

  1. Hi,

    Wieso kann ich den Text auf dem Button nicht einfach so:
    myButton.setAttribute('value', 'Hier klicken!');
    oder so:
    myButton.value = "Hier klicken!";
    ändern?

    Weil das Button-Element nun mal den Elementinhalt als Beschriftung darstellt, und nicht value, was lediglich den Absendewert darstellt.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. @ChrisB
      thx!

  2. @@invrecon:

    nuqneH

    Ich habe ziemlich lange gesucht und herausgefunden, dass man gewisse Eigenschaften eines Buttons auf diese Weise ändern kann:
    myButton.setAttribute('id', 'neuerButton');

    Dann vergiss dieses mühsam erkämpfte Wissen mal wieder; du wirst es kaum brauchen. Attribute stehen als Eigenschaften der Elementobjekte zur Verfügung:
    myButton.id = 'neuerButton';

    IE zickt bei getAttribute()setAttribute() auch gerne mal rum.

    Wieso kann ich den Text auf dem Button nicht einfach so:
    myButton.setAttribute('value', 'Hier klicken!');
    oder so:
    myButton.value = "Hier klicken!";
    ändern?

    Weil die Beschriftung beim 'button'-Element (im Gegensatz zu 'input[@type="button"]') kein Attributwert, sondern Elementinhalt ist:
    <button>Hier klicken!</button> vs. <input type="button" value="Hier klicken!"/>

    "Hier klicken!" ist aber keine sinnvolle Beschriftung.

    Qapla'

    --
    Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
    (Mark Twain)
    1. @Qapla'

      "Hier klicken!" ist aber keine sinnvolle Beschriftung.

      Schon klar :D Ist ja auch nur ein Platzhalter. Danke für die Antwort!
      invrecon

    2. Grüße,

      Dann vergiss dieses mühsam erkämpfte Wissen mal wieder; du wirst es kaum brauchen. Attribute stehen als Eigenschaften der Elementobjekte zur Verfügung:

      was ist mit dem ganzen verkapselungsprinzip? die getter/setter funktionen sollte doch mal die objektorientierten Ansätze sicher und zuverlässig machen ;) ?
      MFG
      bleicher

      --
      __________________________-

      FirefoxMyth
    3. IE zickt bei getAttribute()setAttribute() auch gerne mal rum.

      In welchem Fall und worin besteht das Herumzicken?

      Mathias

      1. @@molily:

        nuqneH

        IE zickt bei getAttribute()setAttribute() auch gerne mal rum.

        In welchem Fall und worin besteht das Herumzicken?

        var myElement = document.getElementById('myElement');  
        myElement.setAttribute('onclick', 'alert("myElement clicked")');
        

        bspw. funzt nicht.[1][2]

        Qapla'

        [1] im IE < 8
        [2] auch nicht bei vorhandenem Element mit der ID 'myElement'

        --
        Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
        (Mark Twain)
        1. Okay, es gibt ein paar Sachen zu beachten:

          • IE < 8 hat keine saubere Unterscheidung zwischen Attributen (attributes) und Eigenschaften (properties). getAttribute liefert daher nicht immer einen String – und hat dafür einen proprietären zweiten Parameter, der allerdings auch nicht wie erwartet funktioniert und einem auch nicht aus der Patsche hilft.

          • Das bedeutet beispielsweise: getAttribute('style') liefert dasselbe wie die style-Eigenschaft, nämlich ein CSSStyleDeclaration-Objekt. getAttribute('checked') liefert fälschlicherweise einen Boolean. getAttribute('value') liefert den aktuellen Wert anstelle den Anfangswert aus dem Markup. Usw.

          • Ein weiteres Resultat davon ist, dass bei setAttribute der gleiche camelCase wie bei den direkten Eigenschaften zu benutzen ist. Siehe <http://de.selfhtml.org/javascript/objekte/node.htm#set_attribute@title=Beachten Sie>. Z.B. getAttribute('htmlFor') anstelle standardgemäß getAttribute('for'). Das funktioniert natürlich nicht browserübergreifend.

          • Wie du auch sagst, akzeptieren on*-Attribute im IE < 8 keine Strings. Hier gilt, dass man Event-Handling immer funktional lösen sollte, entweder mit den on*-Eigenschaften oder in fähigen Browsern mit addEventListener. Abgesehen davon, dass es im IE < 8 ohnehin nicht direkt geht, gibt es keine regulären Vorteile für Event-Handler-Code in Strings.

          • setAttribute('type') ist im IE < 8 nicht bei bestehenden input-Elementen möglich, im IE 8 auch nur eingeschränkt. Strenggenommen ist das keine Standardverletzung, aber es ergeben sich teilweise Unterschiede zu anderen Browsern. input.setAttribute('name') ermöglicht nicht den Zugriff über den Namen über die elements-Collection bzw. getElementsByName (siehe Struppi, Jürgen). Man kann stattdessen das proprietäre document.createElement('<input type="..." name="...">') verwenden. Das sind jetzt beides keine Unterschiede zwischen Attributen und Eigenschaften, es geht m.W. auch nicht über die jeweiligen Eigenschaft.

          Davon abgesehen ist getAttribute/setAttribute im IE meines Wissens harmlos (man ergänze mich). Das Ursprungsbeispiel setAttribute('id') ist also bspw. keine Fehlerquelle. Allerdings sind die obigen Problem ziemlich happig und diese Ausnahmen will man sich besser nicht merken, daher ist deinem Rat zuzustimen, getAttribute/setAttribute weitesgehend zu vergessen.

          Mathias

          1. Hi,

            • setAttribute('type') ist im IE < 8 nicht bei bestehenden input-Elementen möglich, im IE 8 auch nur eingeschränkt. Strenggenommen ist das keine Standardverletzung

            Wenn man DOM Level 1 betrachtet, nicht.
            Aber DOM Level 2 hat das "readonly" für das type-Attribut explizit entfallen lassen - und was sollte ein schreibender Zugriff auf dieses sonst bewirken, wenn nicht eine Änderung des Typs des Inputfeldes?

            Übersehe ich eine Einschränkung, auf Grund derer du das nicht als Standardverletzung einschätzt?

            MfG ChrisB

            --
            RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
            1. Du hast völlig recht, danke für die Ergänzung. DOM 1 HTML sieht type noch als readonly an, DOM 2 HTML nicht mehr und das aktuelle HTML-DOM in HTML5 ebenfalls nicht.

              Im Übrigen definiert HTML5 auch, was der Browser beim Ändern des Typs machen muss.

              Mathias

          2. @@molily:

            nuqneH

            Hier gilt, dass man Event-Handling immer funktional lösen sollte

            Natürlich, full ACK. Das war aber hier nicht das Thema.

            Allerdings sind die obigen Problem ziemlich happig und diese Ausnahmen will man sich besser nicht merken

            *g*

            daher ist deinem Rat zuzustimen, getAttribute/setAttribute weitesgehend zu vergessen.

            Ich hab allerdings noch ein Gegenbespiel, wo man um getAttribute() (noch) nicht drumrumkommt:

            im Markup: <samp id="ultimate-answer" data-ultimate-answer="42"/>

            var ultimateAnswerElement = document.getElementById("ultimate-answer");  
            var ultimateAnswerData = ultimateAnswerElement.dataset.ultimateAnswer;
            

            geht schon in Chrome 9, von den anderen Browsern hab ich grad keine Entwickler-Versionen installiert. Es geht nicht in IE 8, Firefox 3.6.13, Opera 11.00, Safari 5.0.3.

            var ultimateAnswerData = ultimateAnswerElement.dataUltimateAnswer;

            liefert 'undefined'. Warum eigentlich?

            Was browserübergreifend funktioniert, ist

            var ultimateAnswerData = ultimateAnswerElement.getAttribute('data-ultimate-answer');

            Da ist die ultimative Anwort auf die ultimative Frage dann "42".

            Qapla'

            --
            Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
            (Mark Twain)