D.R.: Funktion als Unterobjekt aller HTML-Elemente einbinden

Hallo,

Ich habe mir vor einiger Zeit mal eine Funktion geschrieben, mit der man eine Webseite (deren DOM-Baum) nach bestimmten Attributen, bzw. Eigenschaften durchsuchen kann. Funktioniert also ähnlich, wie „document.getElementsByTagName()“.

Nun möchte ich, dass man die Suche eingrenzen kann, indem man das zu durchsuchende Element vor den „.“ schreibt. Also z.B.

document.body.getElementsBy("className",

Das habe ich im Firefox auch einfach mit folgendem Code erreicht:

  
HTMLElement.prototype.getElementsBy getter = function() {  
return getElementsBy;  
}  

Allerdings zeigen hier sowohl Opera (win), als auch Konqueror (Linux) und IE (win) eine Fehlermeldung, bzw. zeigen den Test-alert nicht an.

An JavaScript 1.7, kann es nicht liegen, da auch FF1.0 keine Probleme damit hatte. Was mache ich falsch? An der Funktion liegt es nicht, da diese vorher auch keine Probleme gemacht hat.

Hier könnt ihr's euch ansehen.

mfg. Daniel

  1. Hi,

    Allerdings zeigen hier sowohl Opera (win), als auch Konqueror (Linux) und IE (win) eine Fehlermeldung, bzw. zeigen den Test-alert nicht an.

    bei Opera bin ich ein wenig verwundert, ihm hätte ich es zugetraut. Konqueror (bzw. zumindest Safari) haben sehr verwunderliche Objekte wie z.B. window["[[DOMElement.prototype]]"], die Du einem Element.prototype zuweisen kannst; wenn dies geschehen ist (und das komische Objekt bereits existierte - dazu müssen bereits irgend welche Ereignisse eingetreten sein), dann kannst Du mit dem prototype verhältnismäßig normal weiter verfahren.

    Der IE ist ein Sonderfall. Ihm musst Du per (Möchtegern-)CSS ein behavior an jedes Element heften, welches eine .htc-Ressource referenziert. Diese muss ein spezielles XML enthalten, in dem ein Script steckt, welches _anstatt_ Deiner prototype-Implementierung etwas Ähnliches macht. Es besteht die Gefahr, dass der IE die Ressource für jedes verdammte Element der Seite neu anfordert.

    Was mache ich falsch?

    Ich behaupte an dieser Stelle einfach mal, dass nicht Du etwas falsch machst, sondern alle Browser bis auf die Gecko-basierten, da es bei allen bis auf diesen ein ziemlicher Krampf ist, das DOM zu erweitern. In der Praxis wirst Du vielleicht einen Rückfall ins funktionale Denken bevorzugen.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hallo,

      Allerdings zeigen hier sowohl Opera (win), als auch Konqueror (Linux) und IE (win) eine Fehlermeldung, bzw. zeigen den Test-alert nicht an.

      …Konqueror (bzw. zumindest Safari) haben sehr verwunderliche Objekte wie z.B. window["[[DOMElement.prototype]]"], die Du einem Element.prototype zuweisen kannst;

      Ich habe das Teil jetzt einfach mal umgeschrieben in…

        
      window["[[DOMElement.prototype]]"].getElementsBy getter = function() {  
      return getElementsBy;  
      }  
      
      

      …was im Konqueror aber irgendwie auch nicht funktioniert :-(
      (das mit der Variable mache ich, lieber erst, wenn's funzt)

      Der IE ist ein Sonderfall. Ihm musst Du per (Möchtegern-)CSS ein behavior an jedes Element heften, welches eine .htc-Ressource referenziert. Diese muss ein spezielles XML enthalten, in dem ein Script steckt, welches _anstatt_ Deiner prototype-Implementierung etwas Ähnliches macht. Es besteht die Gefahr, dass der IE die Ressource für jedes verdammte Element der Seite neu anfordert.

      Och nö, das auch noch? *heul*

      Was mache ich falsch?

      In der Praxis wirst Du vielleicht einen Rückfall ins funktionale Denken bevorzugen.

      Also doch lieber bei der Funktion bleiben und den Suchbereich ggf als Parameter zuweisen, oder?
      Naja, das wird dann wohl das sinnvollste sein. Ich find's eben bloß etwas unübersichtlich, die Funktion so zu schreiben…

        
      getElementsBy("className","meineKlasse","\\b",document.getElementsByTagName("div")[0])  
      
      

      …aber anders geht es anscheinend nicht :-(
      Jedenfalls nicht sinnvoll.

      mfg. Daniel

      1. Hi,

        Ich habe das Teil jetzt einfach mal umgeschrieben in…

        window["[[DOMElement.prototype]]"].getElementsBy getter = function() {
        return getElementsBy;
        }

          
        eio 'oppala. Ich bin nicht sicher, ob die KHTMLer getter kennen. Versuche es wie folgt:  
          
        

        Element.prototype = window["[[DOMElement.prototype]]"];
        Element.prototype.getElementsBy = function() { ... }

          
        Wenn das immer noch nicht klappt, hat der Browser dieses Dingenskirchen vermutlich noch nicht erzeugt. Workaround: Nutze vorher irgend eine bestehende DOM-Methodik, um tief in den Dokumentbaum einzugreifen. Vergleiche [bei Web.de](http://img.web.de/v/home06/js/20061206/base.js) ziemlich weit unten im Code.  
          
        
        > Och nö, das auch noch? \*heul\*  
          
        Wieso? Wir reden hier vom IE. Da wunderst Du Dich, dass gewisse Dinge umständlich sind oder überhaupt gar nicht funktionieren? Anfänger ;-)  
          
        
        > Also doch lieber bei der Funktion bleiben und den Suchbereich ggf als Parameter zuweisen, oder?  
          
        Vrgl. [initTooltips](http://img.web.de/v/home06/js/20061206/dynLib.js), wieder unten im Code.  
          
        
        > Naja, das wird dann wohl das sinnvollste sein. Ich find's eben bloß etwas unübersichtlich, die Funktion so zu schreiben…  
          
        Natürlich, es ist ja auch wider die Natur einer objektorientierten Sprache. Aber was tut man nicht alles für gewisse minderwertige Software-Produkte ... :-/  
          
        
        > …aber anders geht es anscheinend nicht :-(  
        > Jedenfalls nicht sinnvoll.  
          
        Nicht bei DOM, nein. Was den IE betrifft, kannst Du mit prototype praktisch nichts beackern: eigene Objekte, Object, String, Number, Boolean, Date, Array, Function, Error, RegExp. Mehr habe ich nicht gefunden. Bei Gecko lohnt es sich hingegen aufzuzählen, bei welchen Klassen er \_kein\_ prototype beherrscht: ActiveXObject, Layer und Location. Mehr habe ich nicht gefunden :-)  
          
        Cheatah  
        
        -- 
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|  
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html  
        X-Will-Answer-Email: No  
        X-Please-Search-Archive-First: Absolutely Yes
        
        1. Hallo,

          eio 'oppala. Ich bin nicht sicher, ob die KHTMLer getter kennen. Versuche es wie folgt:

          Element.prototype = window["[[DOMElement.prototype]]"];
          Element.prototype.getElementsBy = function() { ... }

            
          Werde ich gleich mal probieren, danke.  
            
          
          > Wenn das immer noch nicht klappt, hat der Browser dieses Dingenskirchen vermutlich noch nicht erzeugt. Workaround: Nutze vorher irgend eine bestehende DOM-Methodik, um tief in den Dokumentbaum einzugreifen. Vergleiche [bei Web.de](http://img.web.de/v/home06/js/20061206/base.js) ziemlich weit unten im Code.  
            
          Werde ich mir mal anschauen.  
            
          
          > > Och nö, das auch noch? \*heul\*  
          >   
          > Wieso? Wir reden hier vom IE. Da wunderst Du Dich, dass gewisse Dinge umständlich sind oder überhaupt gar nicht funktionieren?  
            
          Aber ich kann doch keine extra-Datei einbinden, nur um den IE zu unterstützen…  
            
          
          > Anfänger ;-)  
            
          Das ist gemein. >:o  :'(  
            
          
          > > Naja, das wird dann wohl das sinnvollste sein. Ich find's eben bloß etwas unübersichtlich, die Funktion so zu schreiben…  
          >   
          > Natürlich, es ist ja auch wider die Natur einer objektorientierten Sprache. Aber was tut man nicht alles für gewisse minderwertige Software-Produkte ... :-/  
            
          Wenn es denn wenigstens alle Browser könnten. Aber das ist ja leider auch nicht der Fall. Opera, Konqueror und Safari will ich auf jeden Fall unterstützen.  
            
          
          > > …aber anders geht es anscheinend nicht :-(  
          > > Jedenfalls nicht sinnvoll.  
          >   
          > Nicht bei DOM, nein.  
            
          D.h. man kann im IE mit document.all was erreichen?  
            
          
          > Was den IE betrifft, kannst Du mit prototype praktisch nichts beackern: eigene Objekte, Object, String, Number, Boolean, Date, Array, Function, Error, RegExp.  
            
          Wenn ich im IE ein Objekt referenziere, also über getElements…, liefert er mir „Object“. Müsste es dann nicht mit „Object“ klappen?  
            
            
          Mal 'ne ganz dumme Frage (bitte nicht lachen): Wofür genau steht eigentlich „prototype“? So richtig bin ich da noch nicht dahinter gekommen :-(  
            
          mfg. Daniel
          
          -- 
          [Experten raten von der Verwendung des Internet Explorers ab!](http://web.oesterchat.com/internet-explorer/)  
          [Mein SELF-stylesheet](http://danielrichter.da.funpic.de/SELFForumsCSS.html) | [Darum Firefox!](http://www.firefox-love.de/)  
          [Selfcode](http://forum.de.selfhtml.org/cgi-bin/selfcode.pl): [ie:{ fl:{ br:> va:) ls:\[ fo:| rl:( n4:# ss:| de:> js:| ch:? mo:} zu:}](http://www.peter.in-berlin.de/projekte/selfcode/?code=ie%3A%7B+fl%3A%7C+br%3A%3E+va%3A%7C+ls%3A%23+fo%3A%7C+rl%3A%28+n4%3A%23+ss%3A%7B+de%3A%3E+js%3A%7C+ch%3A%3F+mo%3A%29+zu%3A%7D)
          
          1. Hi,

            Wieso? Wir reden hier vom IE. Da wunderst Du Dich, dass gewisse Dinge umständlich sind oder überhaupt gar nicht funktionieren?
            Aber ich kann doch keine extra-Datei einbinden, nur um den IE zu unterstützen…

            der IE zwingt uns ständig dazu, irgend welche Tode zu sterben. Suche Dir den aus, der am wenigsten schmerzhaft ist. Übrigens ist "IE wird nicht unterstützt" einer dieser Tode.

            Anfänger ;-)
            Das ist gemein. >:o  :'(

            *g* :-)

            Wenn es denn wenigstens alle Browser könnten. Aber das ist ja leider auch nicht der Fall.

            Jepp, viele Hersteller scheinen zu meinen, dass Standards reichlich optional sind - oder zumindest, dass man sich die Rosinen rauspicken könnte. Der (IMHO) einzige Hersteller, der das nicht tut, ist Mozilla.

            Opera, Konqueror und Safari will ich auf jeden Fall unterstützen.

            In der Mathematik gibt es einen Begriff, der "kleinster gemeinsamer Nenner" heißt.

            Nicht bei DOM, nein.
            D.h. man kann im IE mit document.all was erreichen?

            Ich halte document.all für ein Möchtegern-DOM, welches nur dann einer Betrachtung bedarf, wenn der IE 4 eine erhebliche Rolle spielt. Dass es Dir hier hilft, glaube ich nicht wirklich.

            Wenn ich im IE ein Objekt referenziere, also über getElements…, liefert er mir „Object“. Müsste es dann nicht mit „Object“ klappen?

            Leider nicht.

            Mal 'ne ganz dumme Frage (bitte nicht lachen): Wofür genau steht eigentlich „prototype“? So richtig bin ich da noch nicht dahinter gekommen :-(

            Es bezeichnet den - tadaa! - Prototypen eines Objekts, also das, woraus Objekte "entstehen". Ich vergleiche das Konzept ganz gerne mit einer Blaupause - nur dass sich Änderungen an dieser auf alles auswirken, was nach ihnen gebaut wurde ;-)

            Cheatah

            --
            X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
            X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
            1. Hallo,

              der IE zwingt uns ständig dazu, irgend welche Tode zu sterben. Suche Dir den aus, der am wenigsten schmerzhaft ist. Übrigens ist "IE wird nicht unterstützt" einer dieser Tode.

              OK, dann nehm' ich den.

              Jepp, viele Hersteller scheinen zu meinen, dass Standards reichlich optional sind - oder zumindest, dass man sich die Rosinen rauspicken könnte. Der (IMHO) einzige Hersteller, der das nicht tut, ist Mozilla.

              Schade, ich dachte immer, dass sich alle, außer M$ an die Standards halten :-(

              Nicht bei DOM, nein.
              D.h. man kann im IE mit document.all was erreichen?

              Ich halte document.all für ein Möchtegern-DOM,

              OK. Für mich hört sich „nicht bei DOM“ immer wie ein Vergleich mit „document.all“ an. Und was ist mit dem Layer-Modell von NS? ;-)

              Wenn ich im IE ein Objekt referenziere, also über getElements…, liefert er mir „Object“. Müsste es dann nicht mit „Object“ klappen?

              Leider nicht.

              Komisches Teil!

              Um zum Problem zurückzukommen. Ich habe es jetzt so weit geschafft, dass auch Opera mit dem Script klar kommt (ist sogar kürzer ;-)).

              HTMLElement.prototype.getElementsBy = getElementsBy;

              Meinen Konqueror 3.4.2b konnte ich aber leider immer noch nicht überzeugen. Habe folgendes versucht:

                
              HTMLElement.prototype = window["[[DOMElement.prototype]]"];  
              HTMLElement.prototype.getElementsBy = getElementsBy;  
              
              

              Naja, anscheinend kommt Konqueror 3.5.5 ja nun endlich mit dem normalen Script klar!

              mfg. Daniel

              1. Hi,

                Jepp, viele Hersteller scheinen zu meinen, dass Standards reichlich optional sind - oder zumindest, dass man sich die Rosinen rauspicken könnte. Der (IMHO) einzige Hersteller, der das nicht tut, ist Mozilla.
                Schade, ich dachte immer, dass sich alle, außer M$ an die Standards halten :-(

                sagen wir es so: Jeder hält sich _mehr_ an die Standards, als Microsoft es tut. Aber praktisch niemand denkt bei allem, was implementiert wird, daran, ob es mit einem Standard kollidieren kann. Auch Gecko weicht vom Standard ab - aber in aller Regel mit großer Vorsicht, so dass die Risiken gering bleiben.

                OK. Für mich hört sich „nicht bei DOM“ immer wie ein Vergleich mit „document.all“ an.

                Ich halte die Existenz eines document.all für ignorierbar ...

                Und was ist mit dem Layer-Modell von NS? ;-)

                ... und davon habe ich noch nie im Leben etwas gehört. Nein, wirklich nicht, definitiv, definitiv nicht ;-)

                Komisches Teil!

                Tja, wenn es nur auch zum Lachen wäre ... *g*

                Meinen Konqueror 3.4.2b konnte ich aber leider immer noch nicht überzeugen. Habe folgendes versucht:

                Bei Konqueror muss ich wie gesagt leider passen. Hast Du mal versucht, vor diesen Zuweisungen ins DOM zu greifen, um die Objekte zu initialisieren?

                Cheatah

                --
                X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
                X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
                X-Will-Answer-Email: No
                X-Please-Search-Archive-First: Absolutely Yes
                1. Hallo,

                  OK. Für mich hört sich „nicht bei DOM“ immer wie ein Vergleich mit „document.all“ an.

                  Ich halte die Existenz eines document.all für ignorierbar ...

                  OK. Das gefällt mir *g*

                  Und was ist mit dem Layer-Modell von NS? ;-)

                  ... und davon habe ich noch nie im Leben etwas gehört. Nein, wirklich nicht, definitiv, definitiv nicht ;-)

                  Glaube ich dir nicht! Du warst doch schon seit '98 hier im Forum anwesend. Hast du die Postings, die auf dieses DHTML-Modell abzielten etwa alle überlesen?

                  Komisches Teil!

                  Tja, wenn es nur auch zum Lachen wäre ... *g*

                  Allerdings. da tut es gut, zu wissen, dass Firefox & co immer beliebter werden. Hoffentlich wird sich das mit Vista nicht ändern…

                  Meinen Konqueror 3.4.2b konnte ich aber leider immer noch nicht überzeugen. Habe folgendes versucht:

                  Bei Konqueror muss ich wie gesagt leider passen. Hast Du mal versucht, vor diesen Zuweisungen ins DOM zu greifen, um die Objekte zu initialisieren?

                  Wie genau muss ich das machen? Ich dachte, das tut die 1. Zeile in meinem Script aus dem vorherigen Posting?!

                  mfg. Daniel

    2. Hallo,

      Konqueror (bzw. zumindest Safari) haben sehr verwunderliche Objekte wie z.B. window["[[DOMElement.prototype]]"], die Du einem Element.prototype zuweisen kannst

      Safari 2.0.4 scheint HTMLElement.prototype tatsächlich noch nicht zu unterstützen, Konqueror 3.5.5 kann es aber mittlerweile ohne diese Umwege.

      Mathias

      1. Hi,

        Safari 2.0.4 scheint HTMLElement.prototype tatsächlich noch nicht zu unterstützen, Konqueror 3.5.5 kann es aber mittlerweile ohne diese Umwege.

        ah, danke für die Information. Erschreckenderweise haben wir hier in der QS-Abteilung nämlich kein Linux-Testsystem ...

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
  2. Hallo,

    Die Erweiterungen von JavaScript 1.6 und 1.7 sowie Setter und Getter sind proprietäre Erfindungen von Mozilla und werden von keinem anderen Browser unterstützt.

    Zudem gibt es Browser wie IE, die die prototypische Erweiterung von DOM-Klassen nicht unterstützen. Aus diesem Grund existieren Frameworks wie jQuery und Co.

    Mathias

    1. Hallo,

      Die Erweiterungen von JavaScript 1.6 und 1.7 sowie Setter und Getter sind proprietäre Erfindungen von Mozilla und werden von keinem anderen Browser unterstützt.

      Ah, vielen Dank für die Information (Ich wusste doch, dass da irgendwas falsch war). Jetzt habe ich es auch im Opera zum Laufen bekommen:

        
      HTMLElement.prototype.getElementsBy = getElementsBy;  
      
      

      Das funktioniert jetzt schon mal im Opera und Firefox :-). Konqueror muss ich noch testen…

      mfg. Daniel

    2. Hallo Mathias,

      Die Erweiterungen von JavaScript 1.6 und 1.7 sowie Setter und Getter sind proprietäre Erfindungen von Mozilla

      Streng genommen sind alle Erweiterungen an der Sprache durch JS 1.6 und 1.7 Vorgriffe auf Vorschläge der Erweiterung der Sprache durch ECMAScript 4 respektive Javascript 2, also nicht sooo proprietär. Zumindest nicht wie in der alten Zeit, als jeder sein eigenes Süppchen kochte. Hier ist es ein Standardisierungsprozess mit der Mitarbeit von Mozilla, Adobe, Microsoft und IBM.

      ... und werden von keinem anderen Browser unterstützt.

      Tatsächlich wurden Getter und Setter schon für die aktuellen Nightlies in WebKit implementiert.

      Zudem gibt es Browser wie IE, die die prototypische Erweiterung von DOM-Klassen nicht unterstützen. Aus diesem Grund existieren Frameworks wie jQuery und Co.

      Ja, leider.

      (WebKit kann prototype anscheinend inzwischen endlich mal, d.h. es dürfte auch in spätestens einem halben Jahr in Safari landen)

      Tim

  3. Hallo,

    HTMLElement.prototype.getElementsBy getter = function() {
    return getElementsBy;
    }

      
    Äh, Getter und Setter sind für Eigenschaften gedacht, nicht für Methoden - was du hier hast, ist eine einfache Methode. Also ist »getter« ohnehin fehl am Platze.  
      
    Mathias
    
    1. Hallo,

      Äh, Getter und Setter sind für Eigenschaften gedacht, nicht für Methoden - was du hier hast, ist eine einfache Methode. Also ist »getter« ohnehin fehl am Platze.

      Nun ja, die Grenze zwischen Eigenschaften mit Gettern und Settern und Methoden ist ja eh unscharf. Nach der reinen Lehre hast Du aber recht. Und selbst wenn er eine Eigenschaft meinte, so ist doch "getter = function" eine inzwischen missbilligte Syntax, die nur während des Entwicklungsprozesses von JS 1.5 kurz aktuell war und in Zukunft zum Syntax Error wird, glaubt man dem MDC.

      Tim