peterS.: Standardisierung von [getElementsByClassName(s)]

hallo Interessierte,

auf der "whatwg" mailingliste wird nun schon seit langer zeit um eine
spezifikation fuer den DOM getter [getElementsByClassName(s)] gerungen.

der aktuelle stand im dazugehoerigen working draft laesst sich nachlesen:
http://www.whatwg.org/specs/web-apps/current-work/#getelementsbyclassname

einen eindruck ueber die diskussionen auf den haupt- und nebenschauplaetzen
gewinnt man ueber google.

ich weiss, dass es einige muehe kostet, sich in den aktuellen stand der
dinge einzulesen. trotzdem, oder besser sogar dessen ungeachten, moechte
ich von Euch wissen, was Ihr von einer solchen methode hinsichtlich design
(anzahl, typ, namen der argumente) und  arbeitsweise (bedingungen fuer
(un)gueltige matches - typ der zurueckzugebenden trefferliste) erwartet.

ich persoenlich halte den aktuellen wurf fuer nicht ausreichend zuendegedacht.

und da dieses baby hier im forum vor knapp 5 jahren das licht der welt
erblickte, ist es an der zeit, sich aktiv um dessen wohl zu kuemmern.

ich plaediere fuer eine sowohl prototypische implementierung fuer [[Node]]/
[[HTMLElement]] und [[NodeList]] als auch fuer eine *statische*/generische
implementierung fuer [[HTMLDocument]], [[Node]] und [[NodeList]].

es gibt nur ein *one fits all* argument fuer die suche - nennen wir es
[classNames]. dieses darf sowohl [string]-value/[String]-objekt als auch
[RegExp]-objekt sein.
der string-typ erlaubt es, die zu suchenden klassennamen sowohl nur
kommasepariert als auch nur *white space*-separiert als auch in einer
mischung aus beiden zu notieren.
*white space*-separierte klassennamen werden als mutiple klasse erkannt.
kommaseparierte klassennamen werden wie eine ODER liste zu suchender
klassennamen behandelt.
der regulaere ausdruck wird von der methode direkt als filter eingesetzt.

bis hierhin ist soweit alles klar, und eine implementierung, wie gerade
beschrieben, verlinke ich hier schon seit ein paar jahren:
http://www.pseliger.de/jsExtendedApi/jsApi.document.getElementsByClassNames.js

viel raum zur diskussion bieten aber die individuell unterschiedlichen
erwartungshaltungen von entwicklern hinsichtlich des suchergebnisses
beim einsatz multipler klassen.

soll die filterung eher der css-spezifikation folgen - alle moeglichen
losen kombinationen der vorgegebenen klassennamen sind gueltig - oder
soll die vorgegebene reihenfolge der klassennamen ein filterkriterium
sein, so wie es einige der heutigen implementierungen handhaben?

und hier die erstveroeffentlichung einer englischen dikussionsgrundlage
meinerseits:

http://pseliger.de/work-in-progress/js-api.DOM.getElementsByClassNames.dev.w3c-WD.pdf
http://pseliger.de/work-in-progress/js-api.DOM.getElementsByClassNames.dev.w3c-WD.txt
http://pseliger.de/work-in-progress/js-api.DOM.getElementsByClassNames.dev.w3c-WD.js

so long - peterS. - pseliger@gmx.net

--
»Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
  1. Moin!

    ich weiss, dass es einige muehe kostet, sich in den aktuellen stand der
    dinge einzulesen. trotzdem, oder besser sogar dessen ungeachten, moechte
    ich von Euch wissen, was Ihr von einer solchen methode hinsichtlich design
    (anzahl, typ, namen der argumente) und  arbeitsweise (bedingungen fuer
    (un)gueltige matches - typ der zurueckzugebenden trefferliste) erwartet.

    Ich habe nur <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2006-October/007407.htmlqtitle=diese Zusammenfassung> vom Oktober letzten Jahres durchgelesen, und außerdem die derzeitige Spec.

    Meine Anforderungen an getElementsByClassName sind:
    1. Konsistenz innerhalb Javascript
    2. Konsistenz innerhalb der restlichen Umgebung.

    Zu 1.
    Konsistenz innerhalb von Javascript betrifft erstmal die Rückgabe - und da ist ja auch keinerlei Diskrepanz. gEBCN() liefert genau dasselbe zurück, was alle getElements-Funktionen zurückliefern, ein Array von Nodes.

    Als Parameter sollte die Funktion aber ebenso einfach gestrickt sein, also ebenso einen String entgegennehmen, der sagt, welche Elemente gemeint sind.

    Und da kommen wir dann zu 2.
    Konsistenz innerhalb der restlichen Umgebung. Das meint erst einmal HTML und CSS (alles andere wie SVG, MathML etc. basiert auf den Erfahrungen und Vorgaben von HTML).

    In HTML schreibe ich "<p>", in CSS selektiere ich "p", und in Javascript nehme ich getElementsByTagName("p"). Überall "p".

    In HTML schreibe ich id="foo", in CSS selektiere ich "#foo", und in Javascript nehme ich getElementById("foo"). Überall "foo".

    In HTML schreibe ich class="bar", in CSS selektiere ich ".bar", und in Javascript erwarte ich getElementsByClassName("bar"). Überall "bar".

    Soweit ganz einfach. Aber es sind ja mehrere Klassennamen pro HTML-Attribut erlaubt:

    In HTML schreibe ich class="foo bar", in CSS selektiere ich ".foo.bar", in Javascript getElementsByClassName("foo bar").

    Da die Reihenfolge der Klassennamen in HTML und CSS nicht relevant ist, darf sie auch in Javascript nicht relevant sein. Ich muß also foo und bar in allen drei Sprachen vertauschen können, und trotzdem muß dasselbe rauskommen.

    Im Prinzip sollte sich getElementsByClassName() eben so verhalten, wie sich die CSS-Selektoren auch verhalten - halt eingegrenzt auf den Klassennamen.

    Und ich glaube, dass ich nichts davon halte, ein Array als Parameter zu erlauben. Keine andere getElement-Funktion erlaubt so etwas bisher (was deshalb auch ziemlich gut ausschließt, dass es mal soweit kommen wird, weil man das nicht einfach herausfinden kann), die Frage wäre also zu beantworten, welchen Zusatznutzen man davon hätte.

    Die Argumentation lautet: Mit Arrays könnte man mehrere Klassennamen übergeben, die auch Leerzeichen als Namensbestandteil enthalten, weil das Leerzeichen nicht als Trennzeichen genutzt wird. Das halte ich allerdings nicht für stichhaltig, da alle bisherigen Anwendungen den Klassennamen als leerzeichenseparierten String definieren. Dieser theoretische Fall, dass irgendeine künftige Sprache sich ein anderes Zeichen ausdenkt, dürfte vermutlich erfolgreich dadurch verhindert werden, dass man ihn jetzt nicht berücksichtigt.

    es gibt nur ein *one fits all* argument fuer die suche - nennen wir es
    [classNames]. dieses darf sowohl [string]-value/[String]-objekt als auch
    [RegExp]-objekt sein.

    Implementiert irgendeine der anderen getElement-Methoden das RegExp-Objekt als Parameter? Wenn nein, dann soll es auch für Klassennamen nicht erlaubt sein.

    der string-typ erlaubt es, die zu suchenden klassennamen sowohl nur
    kommasepariert als auch nur *white space*-separiert als auch in einer
    mischung aus beiden zu notieren.
    *white space*-separierte klassennamen werden als mutiple klasse erkannt.
    kommaseparierte klassennamen werden wie eine ODER liste zu suchender
    klassennamen behandelt.

    Du meinst: "foo bar" findet alle Elemente, die foo UND bar als Klasse haben.
    "foo,bar" findet alle Elemente, die foo ODER bar haben.

    Wie kriegst du hin, dass "foo,bar baz" alle Elemente findet, die baz UND (foo ODER bar) angehören. Und wenn das so hingekriegt ist, wie definierst du in deinem String dann die Suche nach foo ODER (bar UND baz)?

    Zudem: Kommaseparierung ist ebenfalls in keiner anderen getElement-Methode implementiert. Es wäre wohl sicherlich nett, getElementsById("header,footer,navi") zu machen und dann drei Elemente zurückzukriegen - aber die Methode enthält nicht umsonst getElement -> "nur EIN Element, nicht mehrere".

    der regulaere ausdruck wird von der methode direkt als filter eingesetzt.

    Wie soll das wirken? Wirkt der RegEx auf den in HTML definierten class-String, also mit Leerzeichen? Oder wirkt er auf die separierten Klasseneinzelbezeichner? Und wie kriegst du das konsistent mit den restlichen getElement-Methoden vereinbart? Schlechte Aussichten für dein RegEx-Objekt als Parameter, würde ich sagen.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
    1. gruss Sven

      Ich habe nur diese Zusammenfassung vom Oktober letzten Jahres durchgelesen,
      und außerdem die derzeitige Spec.

      Meine Anforderungen an getElementsByClassName sind:

      1. Konsistenz innerhalb Javascript
      2. Konsistenz innerhalb der restlichen Umgebung.

      das sind auch die meinen - und damit meine ich, dass man die
      konditionierten erwartungshaltungen der nutzer treffen sollte.

      ich glaube, man kann sowohl diesen *default* als auch zusaetzliche
      funktionalitaet in einunddieselbe methode einbauen, ohne das deren
      handhabung wegen *overengineering* aus dem ruder laeuft.

      In HTML schreibe ich class="bar", in CSS selektiere ich ".bar",
      und in Javascript erwarte ich getElementsByClassName("bar").
      Überall "bar".

      Soweit ganz einfach. Aber es sind ja mehrere Klassennamen pro
      HTML-Attribut erlaubt:

      In HTML schreibe ich class="foo bar", in CSS selektiere ich
      ".foo.bar", in Javascript getElementsByClassName("foo bar").

      Da die Reihenfolge der Klassennamen in HTML und CSS nicht
      relevant ist, darf sie auch in Javascript nicht relevant sein.
      Ich muß also foo und bar in allen drei Sprachen vertauschen
      können, und trotzdem muß dasselbe rauskommen.

      Im Prinzip sollte sich getElementsByClassName() eben so
      verhalten, wie sich die CSS-Selektoren auch verhalten -
      halt eingegrenzt auf den Klassennamen.

      wie sind voellig einer meinung, so hab ich das ja ebenfalls
      beschrieben.

      Und ich glaube, dass ich nichts davon halte, ein Array als
      Parameter zu erlauben. Keine andere getElement-Funktion erlaubt
      so etwas bisher ...

      der derzeit aktuelle working draft beruecksichtigt dieses von vielen
      gebrachte argument und stellt die *string only* variante in aussicht.

      ... die Frage wäre also zu beantworten, welchen Zusatznutzen
      man davon hätte.

      genau keinen.

      es gibt nur ein *one fits all* argument fuer die suche - nennen
      wir es [classNames]. dieses darf sowohl [string]-value/[String]-
      objekt als auch [RegExp]-objekt sein.

      Implementiert irgendeine der anderen getElement-Methoden das RegExp-
      Objekt als Parameter? Wenn nein, dann soll es auch für Klassennamen
      nicht erlaubt sein.

      warum eigentlich nicht - bisher wird der erwartungshorizont des oben
      fiktiv eingefuehrten konditionierten benutzers doch getroffen. warum
      sollte man anwendern, die flexibler sind, nicht auch das werkzeug fuer
      mehr flexibilitaet in die hand geben.

      der string-typ erlaubt es, die zu suchenden klassennamen sowohl
      nur kommasepariert als auch nur *white space*-separiert als auch
      in einer mischung aus beiden zu notieren. *white space*-separierte
      klassennamen werden als mutiple klasse erkannt. kommaseparierte
      klassennamen werden wie eine ODER liste zu suchender klassennamen
      behandelt.

      Du meinst: "foo bar" findet alle Elemente, die foo UND bar als
      Klasse haben. "foo,bar" findet alle Elemente, die foo ODER bar
      haben.

      richtig.

      Wie kriegst du hin, dass "foo,bar baz" alle Elemente findet,
      die baz UND (foo ODER bar) angehören.

      ein schoenes beispiel fuer unterschiedliche erwartungen - ich
      interpretiere "foo, bar baz" folgendermassen: finde alle elemente,
      deren [className] "bar" UND "baz" aufweist UND/ODER alle elemente,
      deren [className] "foo" aufweist.

      der kern ist fuer mich immer der _klassen_name_ (einzahl) ob nun
      wirklich alleinstehend oder *white space*-separiert als mutipler
      _klassen_name_ ... das ist wurscht.
      kommata signalisieren aufzaehlung, also eine liste - die wird dann
      als ODER verstanden.

      pseudo-code auf dem weg zur ODER liste:

      classNames.trim().replace((/\s+/g), " "/*shrink*/).split(",");

      Zudem: Kommaseparierung ist ebenfalls in keiner anderen
      getElement-Methode implementiert. Es wäre wohl sicherlich nett,
      getElementsById("header,footer,navi") zu machen und dann drei
      Elemente zurückzukriegen - aber die Methode enthält nicht umsonst
      getElement -> "nur EIN Element, nicht mehrere".

      es gibt doch aber [getElement*s*ByName] und [getElement*s*ByTagName].

      und der methoden-name sollte im zukuenftigen standard auch nicht
      [getElementsByClassName] sondern [getElementsByClassName*s*] lauten.

      der regulaere ausdruck wird von der methode direkt als filter
      eingesetzt.

      Wie soll das wirken? Wirkt der RegEx auf den in HTML definierten
      class-String, also mit Leerzeichen? Oder wirkt er auf die
      separierten Klasseneinzelbezeichner?

      nein, ganz einfach so - pseudocode: elm.className.test(regX);

      Und wie kriegst du das konsistent mit den restlichen getElement-
      Methoden vereinbart? Schlechte Aussichten für dein RegEx-Objekt
      als Parameter, würde ich sagen.

      ich bin da optimistisch - siehe meine anmerkungen dazu weiter oben.

      danke fuer die rueckmeldung - so long - peterS. - pseliger@gmx.net

      --
      »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
      Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
      ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
  2. Hallo Peter,

    auf der "whatwg" mailingliste wird nun schon seit langer zeit um eine
    spezifikation fuer den DOM getter [getElementsByClassName(s)] gerungen.

    Immer noch?

    Ich will nicht der Neinsager sein, aber ich finde langsam die ganzen hochspezialisierten getElement(s)ByWhatever unnötig, wenn es doch im Prinzip umfassendere Möglichkeiten gibt. Mein Favorit ist – abgesehen von der abartigen Namensgebung – die Selectors API; die übrigens aus der mit HTML 5 recht verbandelten Web APIs Working Group stammt. Käme diese DOM API in Browsern zustande, wäre mein Bedarf für den Rest der getElements gedeckt.

    ich persoenlich halte den aktuellen wurf fuer nicht ausreichend zuendegedacht.

    Ein mögliches Problem: So wie ich das verstehe, folgt die WHAT WG IETF-line bestehenden Implentierungen – und für Firefox 3 gibt es schon eine. Eine mögliche umfangreichere Lösung müsste dann wohl abwärtskompatibel zu dieser sein.

    Tim

    1. Moin!

      So wie ich das verstehe, folgt die WHAT WG IETF-line bestehenden Implentierungen – und für Firefox 3 gibt es schon eine.

      Aha, wie ich sehe, setzt der Firefox 3 genau um, was ich von der Methode erwarte. Und nicht mehr.

      Zustimmung für deine Forderung nach einem generischen getWhateverBySomething(). Das dürfte die logische Fortentwicklung sein - und ist genau das, was mir an jQuery so gefällt. :)

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
    2. gruss Tim,

      auf der "whatwg" mailingliste wird nun schon seit langer zeit um eine
      spezifikation fuer den DOM getter [getElementsByClassName(s)] gerungen.

      Immer noch?

      ja leider, die sind nicht die schnellsten.

      Ich will nicht der Neinsager sein, ...

      bist Du auch nicht.

      ... aber ich finde langsam die ganzen
      hochspezialisierten getElement(s)ByWhatever unnötig, wenn es doch im
      Prinzip umfassendere Möglichkeiten gibt. Mein Favorit ist – abgesehen
      von der abartigen Namensgebung – die Selectors Selectors API; die übrigens aus
      der mit HTML 5 recht verbandelten Web APIs Working Group stammt.
      Käme diese DOM API in Browsern zustande, wäre mein Bedarf für den Rest
      der getElements gedeckt.

      ich finde den dort verfolgten ansatz auch eleganter - jquery bedient ja
      auch eine sprechende kurze, intuitive syntax (bis auf dieses unsägliche
      "$"-zeichen). und es gibt noch andere kandidaten in diesem javascript-
      getriebenen *DOM query* umfeld, die ähnlich arbeiten.

      deswegen verliert aber die im gegensatz dazu etwas altbacken wirkende
      "getElementBy"-syntax nicht ihre berechtigung, und wenn auf der "whatwg"
      solche themen dikutiert werden kann man sich ja mal ebenfalls gedanken
      machen ;-)

      Ein mögliches Problem: So wie ich das verstehe, folgt die WHAT WG IETF-line
      bestehenden Implentierungen – und für Firefox 3 gibt es schon eine.
      Eine mögliche umfangreichere Lösung müsste dann wohl abwärtskompatibel
      zu dieser sein.

      ja, da die anderen nicht aus dem knick kommen, setzt "mozilla.org" hier
      mal wieder einen quasistandard, worüber ich nicht wirklich böse bin, denn
      in deren implementierung stimmen der name der methode, die anwendung des
      arguments und das zu erwartende ergebnis eines methodenaufrufs ueberein.

      die "whatwg" wird also in zukunft ueber ein [getElementsByClassName*s*]
      diskutieren muessen - vielleicht verlaeuft das dort aber auch alles im
      sande ... ich weiss es nicht.

      so long - peterS. - pseliger@gmx.net

      --
      »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
      Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
      ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]