Roadster: Dynamisches Laden von Menü-Einträgen / Event Listenern

Hallo miteinander!

Nachdem ich unter tätiger Mithilfe von einigen von euch (insbesondere RIDER sei nochmals lobend erwähnt) es nun geschaft habe, meine Mega-Menüs sowohl grafisch ansprechend als auch funktional zu gestalten, stehe ich nun vor einem neuen Problem, das aus meiner bescheidenen Sicht heraus noch weitaus kniffliger zu lösen erscheint.

(Vorab schonmal Sorry für den Megapost!)

Da meine Menüs trotz aller Bemühungen um inhaltliche Eingrenzung, aufgrund des zu behandelnden Sujets, doch extrem ausufernd sind, erscheint es mir aus Gründen der Zweckmäßigkeit geboten, eine gewisse Benutzer-bezogene Dynamik hinsichtlich des Ladens von Menüeinträgen und dem Hinzufügen bzw. Entfernen von Event Listenern zu implementieren, was meine Fähigkeiten jedoch vor eine (zu) harte Probe stellt!

Nehmen wir einmal folgendes Beispielmenü:

________________________
|                        |
|           /\           |<----- <div> Button 'hoch' (function Rahmen'innen'.scrollTop - 'x' )
|          /__\          |

________________________
Menüpunkt 1
------------------------
Menüpunkt 2
------------------------
Menüpunkt 3           <------ <div> Rahmen 'innen' (overflow-y:scroll)
------------------------
Menüpunkt 4
------------------------
Menüpunkt 5        <--------- <div> Menüelement (eventListener 'click' function loadContent)
------------------------
________________________
__
\  /
/
________________________

Vom äußeren Rahmen mittels overflow:hidden verdeckt, ist für den Betrachter immer nur ein im Vergleich zur gesamten Länge des Menüs verschwindend geringer Teil der Menüelemente zu sehen, das heißt eigentlich würde das ganze (nicht maßstabsgetreu) etwa so aussehen:

_______________                                                              ____________
|_______________|                                                            |------------|
| |-----------| |  Oder, je nachdem, wie weit das Menü gescrollt ist -->     |------------|
| |-----------| |                                                           _|------------|_
| |-----------| |  Da, soweit ich das verstanden habe, die Funktion von    |_|------------|_|
| |-----------| |  Event Listenern ist, in kurzen Intervallen den Status   | |------------| |
|_|-----------|_|  ihres Ziel-Elements zu überprüfen, dürfte klar sein,    | |------------| |
|_|-----------|_|  das bei vielen Duzend Menü-Elementen, das Laufen der    | |------------| |
  |-----------|    dazugehörigen Event Listener nicht gerade speicher-     | |------------| |
  |-----------|    schonend ist, von den Elementen selbst, die ja nicht    |_|------------|_|
  |-----------|    wirklich nonexistent im Sinne von 'display:none'        |_|------------|_|
  |-----------|    sind, sondern ja lediglich unsichtbar sind, im Sinne      |------------|
  |-----------|    von 'visibility:hidden', ganz zu schweigen!               |------------|
  |___________|                                                              |____________|

Die Frage, die ich mir nun stelle ist, ob es nicht möglich ist, einen Bereich außerhalb der Menübox zu definieren, also gewissermaßen eine Grenze, ab der beim scrollen die Menüelemente auf 'display:none' bzw. 'display:block' gesetzt werden und die zu dem jeweiligen Element dazugehörenden EventListener hinzugefügt bzw. wieder entfernt werden, eben abhängig vom 'Status' des Scrollens.

Soweit ich das mitbekommen habe, soll sich über 'element.scrollTop' ja nicht nur ein Wert festlegen lassen, sondern es sollte damit doch auch möglich sein, den Status zu ermitteln, wie weit das entsprechende Element (also das Eltern-Element der Menüpunkte, der 'innere' Rahmen) gescrollt ist.

Im Prinzip müsste es doch also eigentlich möglich sein, eine solche Funktion zusammenzubasteln.
Wie das aber zu bewerkstelligen wäre, entzieht sich leider meiner Kenntnis...

Ich bin wie immer dankbar für jede Hilfe!

Beste Grüße,

Roadster.

  1. Aloha ;)

    Dann dir mal ein Kompliment für die coolen ASCII-Art-Skizzen :D

    Die sind echt hilfreich. Jedenfalls: Dein Problem hört sich für mich lösbar an. Wie, oder ob und wie sinnvoll, darüber muss ich mir noch ein paar Gedanken machen und ein paar Sachen testen.

    Ich melde mich später nochmal... Wollte nur anmerken, dass ich mich dem gern mal annehme...

    Grüße,

    RIDER

    --
    Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
    ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
    1. Aloha ;)

      Also, hab mir jetzt nochmal dein Problem im Detail angesehen. Habe ich das richtig verstanden: Du möchtest einen Teil der Menüpunkte, die sowieso nicht sichtbar sind, auf display:none; stellen und von ihren (klick-bedingten) EventListenern lösen um die Performanz zu steigern?

      Ich bleibe dabei: Mit JavaScript ist das möglich.

      Aber: Wie in meinem Ursprungspost schon angedeutet und von ChrisB ausgeführt, ist das ein sinnloses Unterfangen.

      Du kämpfst da gegen Windmühlen ;) Es bringt dir - da bin ich mir sicher - keinerlei Performance-Steigerung, wenn du das umsetzt. Im Gegenteil: Da eine JavaScript-Lösung auf onscroll hören müsste, das beim Scrollen ständig ausgelöst wird, hättest du einen vollkommen nutzlosen Overhead. Bedenke außerdem: Wenn du Elemente aus deiner scrollbaren Liste entfernst änderst du damit die Position aller anderen Elemente. Das führt dann zu einem lustigen Herumhüpfen deiner Elemente - das willst du sicher nicht miterleben ;)

      Vielleicht hängt da auch ein Grundverständnisproblem (ich glaube ChrisB hat das schon angesprochen): Der EventLISTENER tut nichts (überhaupt nichts), solange das zugehörige Event nicht gefeuert wird. Speichertechnisch ist das auch vollkommen unproblematisch - schließlich hast du (wahrscheinlich) eine einzige Funktion, die von allen EventListenern befeuert wird. Das einzige, was du durch das Entfernen von Elementen an Speicherplatz gewinnst, sind die wenigen paar Variablen, die mit den Mini-Funktionen gefüllt sind, die deine Event-Funktion feuern. Das sind lächerliche Mengen an Speicherplatz und vollkommen unproblematisch. Der Overhead, den du ansprichst (dadurch, dass EventListener, die ganze Zeit am "listenen" sind), tritt nicht auf. Das reine "Listenen" verursacht überhaupt keinen Rechenaufwand (in Zahlen: 0). Der Overhead, der durch das Feuern der Events entsteht, kann von deiner Seite aus gar nicht gesteuert werden, das übernimmt die Engine vollautomatisch und unstopable ;)

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
      ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
      1. Aloha ;)

        Hallo RIDER :)

        Also, hab mir jetzt nochmal dein Problem im Detail angesehen. Habe ich das richtig verstanden: Du möchtest einen Teil der Menüpunkte, die sowieso nicht sichtbar sind, auf display:none; stellen und von ihren (klick-bedingten) EventListenern lösen um die Performanz zu steigern?

        Genau!

        Du kämpfst da gegen Windmühlen ;) Es bringt dir - da bin ich mir sicher - keinerlei Performance-Steigerung, wenn du das umsetzt. Im Gegenteil: Da eine JavaScript-Lösung auf onscroll hören müsste, das beim Scrollen ständig ausgelöst wird, hättest du einen vollkommen nutzlosen Overhead. Bedenke außerdem: Wenn du Elemente aus deiner scrollbaren Liste entfernst änderst du damit die Position aller anderen Elemente. Das führt dann zu einem lustigen Herumhüpfen deiner Elemente - das willst du sicher nicht miterleben ;)

        Ja, das Problem, dass sich durch das adden bzw löschen die Position verschiebt, ging mir auch durch den Kopf. :)

        Vielleicht hängt da auch ein Grundverständnisproblem (ich glaube ChrisB hat das schon angesprochen): Der EventLISTENER tut nichts (überhaupt nichts), solange das zugehörige Event nicht gefeuert wird.

        Und die Frage, wann gefeuert wird, beantwortet der Browser automatisch, hm...

        Speichertechnisch ist das auch vollkommen unproblematisch - schließlich hast du (wahrscheinlich) eine einzige Funktion, die von allen EventListenern befeuert wird.

        Naja, pro Listenpunkt halt eine "Link"-Funktion: 'lösche aktuellen Screen und lade neue Elemente', oder was meinst du mit 'eine' Funktion?

        Das einzige, was du durch das Entfernen von Elementen an Speicherplatz gewinnst, sind die wenigen paar Variablen, die mit den Mini-Funktionen gefüllt sind, die deine Event-Funktion feuern. Das sind lächerliche Mengen an Speicherplatz und vollkommen unproblematisch. Der Overhead, den du ansprichst (dadurch, dass EventListener, die ganze Zeit am "listenen" sind), tritt nicht auf. Das reine "Listenen" verursacht überhaupt keinen Rechenaufwand (in Zahlen: 0). Der Overhead, der durch das Feuern der Events entsteht, kann von deiner Seite aus gar nicht gesteuert werden, das übernimmt die Engine vollautomatisch und unstopable ;)

        Ok. Dann habe ich das wohl tatsächlich einfach falsch verstanden. Oh je, dieser Artikel über Performance von JavaScript, den ich mal gelesen habe, hat echt mehr Schaden bei mir angerichtet als geholfen! :D

        Da stand halt, mann solle EventListener grundsätzlich nur dann hinzufügen, wenn gerade gebraucht und wieder removen, wenn das Zielelement nicht mehr angezeigt wird. LOL, und ich habe in den vergangenen Wochen einen heiden Aufwand betrieben, jeden einzelnen EventListener, den ich irgendwo geadded habe, direkt nach Gebrauch wieder zu removen und erst vor dem nächsten Einsatz
        wieder zu readden!

        Also, dass heißt, theoretisch (ich betone theoretisch, Stichwort Benutzbarkeit...) könnte ich auch, sagen wir - TAUSEND - EventListener am Listenen haben, ohne dass sich das negativ auf die Performance auswirkt?

        Dann könnte ich mir 'removeEventListener' ja im Prinzip auch komplett sparen und einfach am Anfang meines Scripts in einer episch lange Liste allen sensitiven Elementen meiner Seite ihren EventListener adden...

        Tja, wow!

        Jedenfalls vielen Dank für die erhellenden Worte (auch an Chris)!

        Gruß,

        Roadster.

        1. Aloha ;)

          Naja, pro Listenpunkt halt eine "Link"-Funktion: 'lösche aktuellen Screen und lade neue Elemente', oder was meinst du mit 'eine' Funktion?

          Genau, ja.

          Ok. Dann habe ich das wohl tatsächlich einfach falsch verstanden. Oh je, dieser Artikel über Performance von JavaScript, den ich mal gelesen habe, hat echt mehr Schaden bei mir angerichtet als geholfen! :D

          Da stand halt, mann solle EventListener grundsätzlich nur dann hinzufügen, wenn gerade gebraucht und wieder removen, wenn das Zielelement nicht mehr angezeigt wird. LOL, und ich habe in den vergangenen Wochen einen heiden Aufwand betrieben, jeden einzelnen EventListener, den ich irgendwo geadded habe, direkt nach Gebrauch wieder zu removen und erst vor dem nächsten Einsatz
          wieder zu readden!

          Also, dass heißt, theoretisch (ich betone theoretisch, Stichwort Benutzbarkeit...) könnte ich auch, sagen wir - TAUSEND - EventListener am Listenen haben, ohne dass sich das negativ auf die Performance auswirkt?

          Dann könnte ich mir 'removeEventListener' ja im Prinzip auch komplett sparen und einfach am Anfang meines Scripts in einer episch lange Liste allen sensitiven Elementen meiner Seite ihren EventListener adden...

          Meiner Einschätzung nach: ja. Trotzdem kann es nicht schaden, durch intelligent design etwas an Speicherplatz etc. einzusparen. Z.B. indem du, wie bei dem von uns durchgekauten Beispiel, Funktionen generalisierst und in den Event-Listenern nur noch den parametergestützten Aufruf der generalisierten Funktion notierst. Das hat viele Vorteile - vielleicht auch einen Performancevorteil. Ich glaube aber nicht, dass das tatsächlich spürbar wird ;)

          Vielleicht kann dir jemand, der mehr oder tiefergehend Ahnung von JavaScript hat (1UnitedPower vielleicht?) da noch eine fundiertere Erklärung oder Begründung geben. Was ich geschrieben hatte entspringt halt meinem Laienwissen und persönlicher Erfahrung.

          Jedenfalls vielen Dank für die erhellenden Worte (auch an Chris)!

          Immer wieder gerne ;)

          Grüße,

          RIDER

          --
          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
          ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
          1. Hakuna matata!

            Vielleicht kann dir jemand, der mehr oder tiefergehend Ahnung von JavaScript hat (1UnitedPower vielleicht?) da noch eine fundiertere Erklärung oder Begründung geben. Was ich geschrieben hatte entspringt halt meinem Laienwissen und persönlicher Erfahrung.

            Also JavaScript und Performance. Es gibt zich Arten, um selbst die letzte nano Sekunde aus einer for-Schleife herauszukitzeln. Es gibt Leute, die befassen sich sehr ausführlich mit der Theorie dahinter, also was die JavaScript-Engine machen muss, um diese oder jene for-Schleifen-Variation auszuführen. Die Resultate aus der Theorie werden dann mit Benchmarktests gemessen und untereinander verglichen. Das ist sehr wichtige Arbeit, keine Frage.

            Aber, es ist ein Fehler hinzugehen, nachdem man so einen Test gelesen hat, und nur noch die hochoptimierte for-Schleife zu benutzen. Denn die Millisekundenbruchteile, die man dadurch sparen kann, sind verschwindend gering, wenn man sie gegen die Zeit aufwiegt, die bei komplexen DOM-Manipulationen verloren geht. Und nur um das sicherzustellen, die for-Schlefe und die DOM-Manipulationen haben hier nur exemplarischen Charakter.

            In den allerwenigsten Fällen, wird man überhaupt Probleme mit der Performanz kriegen, und wenn doch, dann ist es wenig hilfreich auf Verdacht hier und da ein paar for-Schleifen zu optimieren oder ein paar Eventlistener zu lösen. In solchen Fällen, sollte man sich bemühen erstmal rauszufinden, welcher Übeltäter das Programm so langsam werden lässt, also wo der Flaschenhals versteckt ist. Dann sollte man sich gezielt überlegen, was man dagegen tun kann, und dabei hilft einem dann wieder die Theorie.

            Meine Divise ist deshalb von vornerein und immer, wenn es möglich ist, gut leserlichen und ausdrucksstarken Quelltext zu schreiben und da sind Performanz-Tweaks meistens nun mal kontraproduktiv.

            Und wenn es dann doch mal ans Eingemachte geht, dann ist der Griff zum CPU-Profiler bzw. zum Memory-Profiler der erste Schritt, den man unternehmen sollte.

            --
            “All right, then, I'll go to hell.” – Huck Finn
  2. Hi,

    Nehmen wir einmal folgendes Beispielmenü:

    … und werfen wir es dann gleich wieder weg, weil es unsemantische Div-Suppe ist.

    (Und dann zeichnen wir das ordentlich mit UL/OL und LI aus.)

    Und das folgende zitiert sich jetzt ganz bescheiden, weil du den Text zwischen deine ASCII-Art gepackt hast:

    | |-----------| |  Da, soweit ich das verstanden habe, die Funktion von    |_|------------|_|
    | |-----------| |  Event Listenern ist, in kurzen Intervallen den Status   | |------------| |
    |_|-----------|_|  ihres Ziel-Elements zu überprüfen,

    Nein.

    Bzw. Jein.

    Das handelt alles der Browser intern für dich, auf JS-Ebene bekommst du damit nicht in Berührung – da bekommst du einfach nur mit, dass die Events „gefeuert“ werden.

    (Bestimmt Events feuern aber unter Umständen sehr oft, z.B. der scroll-Event – das sollte man dann schon etwas intelligenter handhaben, als bei jedem feuern sofort etwas zu machen.)

    dürfte klar sein,    | |------------| |
    |_|-----------|_|  das bei vielen Duzend Menü-Elementen, das Laufen der    | |------------| |
      |-----------|    dazugehörigen Event Listener nicht gerade speicher-     | |------------| |
      |-----------|    schonend ist,

    Sowas handelt in diesem Umfang jeder Browser problemlos.

    von den Elementen selbst, die ja nicht    |_|------------|_|
      |-----------|    wirklich nonexistent im Sinne von 'display:none'        |_|------------|_|
      |-----------|    sind, sondern ja lediglich unsichtbar sind, im Sinne      |------------|
      |-----------|    von 'visibility:hidden', ganz zu schweigen!               |------------|

    Auch das ist nur ein Fliegenschiss.

    Die Frage, die ich mir nun stelle ist, ob es nicht möglich ist, einen Bereich außerhalb der Menübox zu definieren, also gewissermaßen eine Grenze, ab der beim scrollen die Menüelemente auf 'display:none' bzw. 'display:block' gesetzt werden und die zu dem jeweiligen Element dazugehörenden EventListener hinzugefügt bzw. wieder entfernt werden, eben abhängig vom 'Status' des Scrollens.

    Das würde das ganze aufwendiger ([auch] für dich in der Umsetzung) und höchstvermutlich weniger performant machen.

    Im Prinzip müsste es doch also eigentlich möglich sein, eine solche Funktion zusammenzubasteln.

    Wäre es. Wäre aber vergebliche Liebesmüh’, bzw. vermutlich sogar eher kontraproduktiv.

    MfG ChrisB

    --
    Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
  3. Hallo miteinander!

    Da mir eure profunden Kenntnisse nun schon einige Male das Leben (oder wenigstens die Arbeit an meinem Webseiten-Projekt) entscheidend erleichtert haben, habe ich mich entschlossen, meinen eigenen Thread zu kapern, um noch einmal ein paar Fragen loszuwerden! ;)

    Also. Wie schon öfters erwähnt, gibt es auf meiner Seite eine Unmenge an content, und - schlimm genug, dass das alles irgendwie verlinkt und zugänglich gemacht werden muss - ist es natürlich auch so, dass sich die Frage stellt, wie der content selbst dargestellt werden soll.

    Vielleicht verdeutlicht sich das Problem, wenn ich euch ein kleines Beispiel gebe:

    Ich sitze vor meiner Webseite und lese mir ein juristisches Fall-Beispiel durch. Dann will ich unter Umständen auch damit im Zusammenhang stehende Gesetzes-Paragraphen nachschlagen, mir gesetzliche Definitionen ansehen, mir alternative Betrachtungsweisen, sprich andere Texte anlesen, mir zum besseren Verständnis Schemata und Organigramme anschauen oder mir im Seiten-eigenen Texteditor Notizen machen - und das freilich ohne Instanzen zu wechseln oder sonst einen größeren Aufwand betreiben zu müssen!

    Nun ist es mir nach einigen Fehlschlägen zwar tatsächlich gelungen, diese Anforderungen layout-technisch so auf die Reihe zu bekommen, dass all das sehr komfortabel möglich ist, aber ein sehr grundlegendes Problem verhagelt mir leider noch die Freude darüber:

    Ich habe zwar erfolgreich die Seiten-Texte, also den eigentlichen Inhalt von den darstellenden Seiten-Elementen abgekoppelt, aber die Seiten-Elemente selbst sind natürlich nach wie vor in die Statik der HTML-Datei eingebunden, was vor dem Hintergrund der oben beschriebenen Anforderungen an die Funktionalität natürlich wenig vorteilhaft ist!

    Zum besseren Verständnis meiner weiteren Ausführungen hier mal ein Screenshot einer (beliebigen) Unter-Seite mit den entsprechenden Seiten-Elementen:

    http://www.directupload.net/file/d/3829/g9gcs4co_jpg.htm

    Die Kopfzeile erklärt sich von selbst; Die Links in der Zweiten Zeile 'beladen' das Menü rechts mit neuen Listen: zur Navigation, zu Gesetzen, Texten usw.; Der 'Behalten'-Button in der Weißen Box sorgt dafür, dass die Box minimiert und auf einem Stapel unterhalb des Menüs 'abgelegt' wird, von wo aus sie bei bedarf wieder aufgerufen werden kann, ohne dass man den entsprechenden content mühsam wieder aus den Menü-Listen ausgraben müsste, - also quasi eine Ablagefunktion.

    Entscheidend ist nun diese Weiße Box mit dem Textinhalt!

    Hier hatte ich zunächst per .class eine Standardbox mit min-height definiert und in HTML eine lange Liste an "leeren Hüllen" angelegt, was sich aber bei der Bearbeitung in javascript schnell als ziemlicher Alptraum dargestellt hat, da bei jedem Menü-Listenpunkt-Aufruf ja ersteinmal gecheckt werden muss, welche "Hülle" gerade frei ist, um mit content beladen zu werden, von der Reihenfolge der Darstellung dieser Boxen mal ganz abgesehen...

    Das hat mich dann auf den Trichter gebracht, dass ich die weißen, Inhalt-tragenden Boxen ja auch bei Bedarf gleich ganz über javascript erstellen und hernach wieder verwerfen könnte! (Und bevor jetzt Einsprüche kommen: Ja, ich weiß, die Seite 'sollte' auch ohne script funktionieren. Tut sie aber nicht. Die Wahl habe ich getroffen und es ist ja auch nur mein ganz persönliches - und kein kommerzielles Projekt für einen Dritten.)

    Also habe ich einmal folgenden Code zusammengebastelt:

    function selectAGGp1OnClick(){// function nach click auf einen Menülistenpunkt  
    createContentBox("AGG §1 Ziel des Gesetzes",textAGGp1(),"AGGp1");}  
      
    // headline ist klar, textAGGp1 ist der Paragraphentext, AGGp1 ist eine Markierung  
      
    function createContentBox(headline,text,name){  
    var boxContainer=document.getElementById("boxContainer"); // da solls rein  
    var contentBox=document.createElement("DIV"); // neue Box  
    var contentBoxHeader=document.createElement("DIV"); // Rahmen für:  
    var contentBoxHeadLine=document.createElement("DIV"); // headline und  
    var contentBoxKeepButton=document.createElement("DIV"); // 'Behalten'-button  
    var contentBoxKeepButtonText=document.createElement("P"); // und  
    var contentBoxCloseButton=document.createElement("DIV"); // 'Schließen'-button  
    var contentBoxCloseButtonText=document.createElement("P");  
    var contentBoxBody=document.createElement("DIV"); // Rahmen für das  
    var contentTextField=document.createElement("P"); // Textfeld  
    var encodedTxt=encodeURI(headline);  
    var decodedTxt=decodeURI(encodedTxt); // Paragraphen-Zeichen müssen sein  
    boxContainer.appendChild(contentBox);  
    contentBox.appendChild(contentBoxHeader);  
    contentBox.appendChild(contentBoxBody);  
    contentBox.insertBefore(contentBoxHeader,contentBoxBody);  
    contentBoxHeader.appendChild(contentBoxHeadLine);  
    contentBoxHeader.appendChild(contentBoxKeepButton);  
    contentBoxHeader.appendChild(contentBoxCloseButton);  
    contentBoxHeader.insertBefore(contentBoxHeadLine,contentBoxKeepButton,contentBoxCloseButton);  
    contentBoxKeepButton.appendChild(contentBoxKeepButtonText);  
    contentBoxCloseButton.appendChild(contentBoxCloseButtonText);  
    contentBoxBody.appendChild(contentTextField);  
    contentBox.id="contentBoxPlus"; // nur ein manueller Notbehelf  
    contentBox.className="contentBox fadeIn"; // Boxen werden immer weich ein- und ausgeblendet  
    contentBoxHeader.className="contentBoxHeader";  
    contentBoxHeadLine.className="contentBoxHeadLine";  
    contentBoxKeepButton.className="contentBoxKeepButton";  
    contentBoxCloseButton.className="contentBoxCloseButton";  
    contentBoxBody.className="contentBoxBody";  
    contentBoxAddEventListener();  
    contentBoxHeadLine.innerHTML=decodedTxt;  
    contentBoxKeepButtonText.innerHTML="Behalten";  
    contentBoxCloseButtonText.innerHTML="Schliessen"; // Auch 'ß' ist ein Sonderzeichen  
    contentTextField.className=name; // daran kann ich die Box identifizieren  
    contentTextField.innerHTML=text;  
    contentBox.style.display="block";  
    contentBox.style.animationPlayState="running";}
    

    Die weiße Box, die ihr auf dem Screenshot gesehen habt, wurde so erstellt, also prinzipiell funktioniert es.

    Aber: Was nicht funktioniert, dass sind die Sonderzeichen! Wie ihr auf dem Screenshot sehen könnt, fehlt das Paragraphen-Zeichen aus der Überschrift: Obwohl ich in der Funktion den gleichen Code (en- und decodeURI()) verwendet habe, der bei den HTML-erstellten Boxen immer prima funktioniert hat, klappt das bei den in JS erstellten Boxen leider überhaupt nicht!

    Außerdem finde ich die Frage der Namensvergabe sehr problematisch: Welche ID soll die erstellte Box bekommen? - Am besten wäre es natürlich, wenn man die Namensvergabe irgendwie automatisieren könnte, also je nach dem, welche ID's schon vergeben sind, contentBox1, contentBox2, contentBox739, ..., contentBox[n]. (und natürlich die Buttons respektive!)

    Leider habe ich keine Ahnung, wie ich das anstellen soll...

    Wäre toll, wenn mir da jemand weiterhelfen könnte!

    Zuletzt davon einigermaßen unabhängig: Weiß jemand von euch, ob es eine Möglichkeit gibt, via CSS oder JS, bei dem Attribut 'opacity' einen Verlauf zu erzeugen, also dass innerhalb eines Rahmens die transparenz graduell zu- bzw. abnimmt?!

    Wenn nämlich mehrere von den weißen Inhaltsboxen offen sind und diese gescrollt werden, dann verschieben sie sich unter die mit position:fixed festgepinnte Kopfleiste, und da wäre es sehr nice, wenn der unter der Leiste befindliche Teil smooth ausblenden würde, ohne das es da einen cut gäbe...

    Für Hilfe und Anregungen wie immer in Dankbarkeit ergeben und mit besten Grüßen,

    euer

    Roadster.

    1. Aloha ;)

      Ich sitze vor meiner Webseite und lese mir ein juristisches Fall-Beispiel durch. Dann will ich unter Umständen auch damit im Zusammenhang stehende Gesetzes-Paragraphen nachschlagen, mir gesetzliche Definitionen ansehen, mir alternative Betrachtungsweisen, sprich andere Texte anlesen, mir zum besseren Verständnis Schemata und Organigramme anschauen oder mir im Seiten-eigenen Texteditor Notizen machen - und das freilich ohne Instanzen zu wechseln oder sonst einen größeren Aufwand betreiben zu müssen!

      Du hast dir was vorgenommen ;)

      Zum besseren Verständnis meiner weiteren Ausführungen hier mal ein Screenshot einer (beliebigen) Unter-Seite mit den entsprechenden Seiten-Elementen:

      http://www.directupload.net/file/d/3829/g9gcs4co_jpg.htm

      Nett, das mal in Action zu sehen. Jetzt verstehe ich auch, dass dich die Scrollbalken aus gutem Grund gestört haben.

      (Und bevor jetzt Einsprüche kommen: Ja, ich weiß, die Seite 'sollte' auch ohne script funktionieren.

      Nein, du hast das Prinzip nicht verstanden ;) Nicht die Seite sollte ohne Script funktionieren. Grundsätzlich ist Dynamik in Seiten so gut wie nur über Javascript überhaupt möglich. Wenn das gesamte Anforderungsprofil der Seite (wie in diesem Fall hier) auf Dynamik ausgelegt ist, dann ist es nur recht und billig vom User zu verlangen, Javascript dafür zu aktivieren. Es ist nur dann angebracht auf den Einsatz von JavaScript mindestens teilweise zu verzichten, wenn die Funktionalitäten auch ohne Javascript realisierbar sind. Das sind sie in deinem Fall aber nicht. (Bezogen auf die nackte Scrollleiste alleine waren sie das - schließlich konnten wir eine Lösung finden, die auch ohne Javascript scrollen ermöglicht) Ich formuliere gerne so: JavaScript ist eine Sache für Komfortfeatures. Und deine Seite ist imho von vorne bis hinten ein Komfortfeature ;)

      Tut sie aber nicht. Die Wahl habe ich getroffen und es ist ja auch nur mein ganz persönliches - und kein kommerzielles Projekt für einen Dritten.)

      Und eine bewusste Entscheidung seitens des Inhabers ist sowieso nicht in Frage zu stellen ;)

      Also habe ich einmal folgenden Code zusammengebastelt:
      [...]

      Aber: Was nicht funktioniert, dass sind die Sonderzeichen! Wie ihr auf dem Screenshot sehen könnt, fehlt das Paragraphen-Zeichen aus der Überschrift: Obwohl ich in der Funktion den gleichen Code (en- und decodeURI()) verwendet habe, der bei den HTML-erstellten Boxen immer prima funktioniert hat, klappt das bei den in JS erstellten Boxen leider überhaupt nicht!

      Warum überhaupt das kodieren und ent-kodieren? Du kannst doch einfach den String nutzen, der in headline gespeichert ist. Schonmal versucht? Wenn du - warum auch immer - ein Äquivalent zu htmlspecialchars auf js-Basis suchst, dann schau mal hier (Erste Antwort).

      Außerdem finde ich die Frage der Namensvergabe sehr problematisch: Welche ID soll die erstellte Box bekommen? - Am besten wäre es natürlich, wenn man die Namensvergabe irgendwie automatisieren könnte, also je nach dem, welche ID's schon vergeben sind, contentBox1, contentBox2, contentBox739, ..., contentBox[n]. (und natürlich die Buttons respektive!)

      Eigentlich einfach. Folgende Routine spuckt dir immer ein unvergebenes x aus:

      var x = 0;  
      while (document.getElementById('contentBox'+x) != null) { x++; }
      

      Wäre toll, wenn mir da jemand weiterhelfen könnte!

      Ich hoffe schon, dass dir das weiterhilft ;)

      Zuletzt davon einigermaßen unabhängig: Weiß jemand von euch, ob es eine Möglichkeit gibt, via CSS oder JS, bei dem Attribut 'opacity' einen Verlauf zu erzeugen, also dass innerhalb eines Rahmens die transparenz graduell zu- bzw. abnimmt?!

      Mit etwas Umdenken eigentlich auch einfach: Wenn der Berg nicht zum Prophet kommt, muss der Prophet eben zum Berg kommen. Oder: Wenn die Box nicht vor dem Hintergrund verschwinden will, dann soll sie eben dahinter verschwinden :D

      Man nehme eine Box über die gesamte gewünschte Breite und mit genügend hohem z-index. Die bekommt per linear-gradient einen vertikalen Farbverlauf zwischen der Hintergrundfarbe (oben) und transparent (unten). Diese knalle man da hin und in der Höhe, wie und wo der smoothe Fading-Effekt geschehen soll. Und voila, die Dinge scrollen unten durch und werden immer blasser.

      Wenn nämlich mehrere von den weißen Inhaltsboxen offen sind und diese gescrollt werden, dann verschieben sie sich unter die mit position:fixed festgepinnte Kopfleiste, und da wäre es sehr nice, wenn der unter der Leiste befindliche Teil smooth ausblenden würde, ohne das es da einen cut gäbe...

      Dann musst du deine Fading-Box eben auch mit fixed anpinnen ;)

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
      ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
      1. Aloha ;)

        Hallo RIDER :)

        Du hast dir was vorgenommen ;)

        Man wächst an seinen Aufgaben! :D

        Nett, das mal in Action zu sehen. Jetzt verstehe ich auch, dass dich die Scrollbalken aus gutem Grund gestört haben.

        Hatte gehofft, dass das jemandem auffällt! ;)

        [...] Und deine Seite ist imho von vorne bis hinten ein Komfortfeature ;)

        Das ist wahr. Die perfekte Synthese aus elegantem Design und Funktionalität™ :)

        Naja, im Ernst, aber da triffst du den Nagel auf den Kopf!

        Ich denke, das Design sollte, sofern dies nicht der primäre Zweck einer Seite ist, sich immer der durch die eigentlichen Thematik indizierten Funktionalität unterordnen, aber ich denke auch, dass Design und Funktionalität nicht zwingend im Widerspruch zueinander stehen, sondern dass im Gegenteil, gutes Design eine Grundvoraussetzung für Funktionalität darstellt:

        Wenn ich eine Seite so gestalten kann, dass sie ein Optimum an Bedienbarkeit bietet und die Bedienung obendrein auch noch ein sinnlicher Genuss ist - auf das der Benutzer sich GERNE auf der Seite aufhält(!) - dann ist dem eigentlichen Zweck umso mehr gedient; Im Optimalfall tritt das Design dann nach einer Weile auch automatisch in den Hintergrund und wird nurnoch als Funktionalität wahrgenommen.

        Bei dem Versuch, sich diesem Ideal anzunähern, ist Detailverliebtheit sicher kein Hindernis, sondern eher Voraussetzung! ;)

        Warum überhaupt das kodieren und ent-kodieren? Du kannst doch einfach den String nutzen, der in headline gespeichert ist. Schonmal versucht?

        Wenn das funktioniert hätte, wäre ich nie auf die Idee gekommen, den Quatsch zu kodieren! :D

        Wenn du - warum auch immer - ein Äquivalent zu htmlspecialchars auf js-Basis suchst, dann schau mal hier (Erste Antwort).

        Das schaue ich mir nachher mal näher an, thx für die Info!

        Eigentlich einfach. Folgende Routine spuckt dir immer ein unvergebenes x aus:

        var x = 0;

        while (document.getElementById('contentBox'+x) != null) { x++; }

          
        
        > Ich hoffe schon, dass dir das weiterhilft ;)  
          
        Ganz bestimmt! Aber wirklich verstanden hab ich's noch nicht! :)  
          
        Wie komme ich in meiner createBox-Funktion von `contentBox.id="";`{:.language-javascript} zu deiner 'Routine'? (Oder umgekehrt?)  
          
        Irgendwie stehe ich auf dem Schlauch!  
          
        Wie baue ich deinen Schnippsel so in meine Funktion ein, dass die Boxen fortlaufend nummeriert werden und ich diese Information auch irgendwie abrufen und weitergeben kann?  
          
        Ich muss ja auch dem EventListener, der meine 'infinite-fade-animation' bei der ersten Iteration abfängt und per Funktion das Element auf "paused" und "class default" setzt die ID irgendwie durchgeben, ganz zu schweigen von den anderen, individuellen Funktionen, die da an jeder Box noch dranhängen?  
          
        
        > Man nehme eine Box über die gesamte gewünschte Breite und mit genügend hohem z-index. Die bekommt per [linear-gradient](http://wiki.selfhtml.org/wiki/CSS/Eigenschaften/Hintergrundfarben_und_-bilder/linear-gradient%28%29) einen vertikalen Farbverlauf zwischen der Hintergrundfarbe (oben) und transparent (unten). Diese knalle man da hin und in der Höhe, wie und wo der smoothe Fading-Effekt geschehen soll. Und voila, die Dinge scrollen unten durch und werden immer blasser.  
          
        Top! So sollte es funktionieren!  
          
        Das 'transparent' hatte ich gar nicht mehr auf dem Schirm! ;)  
          
        Besten Dank und Gruß,  
          
        Roadster.
        
      2. Aloha ;)

        Hallo RIDER :)

        Oh man, sorry, aber ich begreife es nicht! :(

        Also deine Routine checkt, ob es schon ein gleichnamiges Element gibt, und falls nein, spuckt es eine Zahl aus, richtig?

        Aber wie kann ich damit etwas machen?

        Normalerweise kenne ich es bislang nur so, dass ich wenn ich das Ergebnis irgendeiner Funktion weiterverarbeiten will, ich am Ende der Funktion sowas stehen habe, wie function(){xyz; return 'wert';}, so dass ich dann nur noch var 'wert'=funktion(); schreiben muss und dann damit was machen kann. Aber irgendwie will mir das hier einfach nicht gelingen...

        Wenn ich versuche { x++; } auf die Art einzufügen, bekomme ich undefined, und x = 0 geht auch nicht.

        Hab bei meinen Versuchen zwischendurch sogar meinen Browser gecrasht, aber das scheint bei laienhafter Bedienung von etwas so risikoreichem wie einer 'while-Schleife' wohl nicht ausgeschlossen! ;)

        Mhhh...

        Gruß,

        Roadster.

        1. Aloha ;)

          Hallo RIDER :)

          Oh man, sorry, aber ich begreife es nicht! :(

          Kein Problem, ich brauch ja auch eine Daseinsberechtigung :D

          Also deine Routine checkt, ob es schon ein gleichnamiges Element gibt, und falls nein, spuckt es eine Zahl aus, richtig?

          Genau.

          Aber wie kann ich damit etwas machen?

          Die baust du in deine Create-Box-Funktion (also genauso wie sie da steht, copy+paste) ein. Und zwar irgendwo bevor du die id festlegst. Und danm machst du einfach nur contentBox.id = "contentBox"+x;

          Event-Listener und Co. kannst du ja auch schon im Konstruktor anhängen. Wenn nicht hab ich das Problem diesbezüglich nicht verstanden ;)

          Normalerweise kenne ich es bislang nur so, dass ich wenn ich das Ergebnis irgendeiner Funktion weiterverarbeiten will, ich am Ende der Funktion sowas stehen habe, wie function(){xyz; return 'wert';}, so dass ich dann nur noch var 'wert'=funktion(); schreiben muss und dann damit was machen kann. Aber irgendwie will mir das hier einfach nicht gelingen...

          Für so nen Zweizeiler ne Funktion mit Rückgabewert zu schreiben wäre zwar möglich, aber nicht notwendig.

          Hab bei meinen Versuchen zwischendurch sogar meinen Browser gecrasht, aber das scheint bei laienhafter Bedienung von etwas so risikoreichem wie einer 'while-Schleife' wohl nicht ausgeschlossen! ;)

          Jaaa. Passiert mir teils auch :D deshalb benutzt man while ja nur so sparsam ;)

          Grüße,

          RIDER

          --
          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
          ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
          1. JAHAHAAAAAA!!!!

            Es läuft!!!

            LOL, und ich stelle gerade fest, dass es eigentlich auch schon die ganze Zeit lief, ich nur zu dämlich war, es zu erkennen!!! :D

            Weil bei Ausgabe der ID immer "contentBox0" (oder bei weniger erfolgreichen Versuchen 'undefined') kam und ich in deinem Schnippsel immer var x = 0vor der Schleife und!=nullin der Schleifenbedingung gelesen habe, bin ich ohne nachzudenken irgendwie immer davon ausgegangen, dass das Ergebnis "contentBox1" sein müsste, und "0" den Wert aus der Ursprungsvariable darstellt und nicht das Ergebnis der erfolgreichen Prozedur! :)

            Fabelhaft, was für ein Hornochse ich bin! Au man! :D

            Genial, jetzt hält mich nichts mehr auf! (Wenigstens bis zum Morgengrauen^^)

            Danke, danke, danke!

            Gruß,

            Roadster.

  4. Hallo miteinander!

    Ich stehe mal wieder vor einem Problem, dessen Lösung ich trotz intensivster Bemühungen nicht finde. Im wahrsten Sinne des Wortes! Es geht nämlich um das Auffinden von Elementen, die mittels JavaScript dynamisch erstellt wurden und die sich auf display:none befinden.

    Genauer gesagt, geht es um verschachtelte Elemente, die automatisch erstellt und automatisch mit IDs versehen wurden:

    Wir haben als <div> Eltern-Element den "boxContainer" - dessen Name ist bekannt. ;)

    Darin befinden sich automatisch erstellte "contentBoxen", <div> Elemente, die wiederum einen "contentBoxHeader" <div> und einen "contentBoxBody" <div> als Kind-Elemente haben.

    Im <div> "contentBoxBody" befindet sich nun das gesuchte <p> Element "contentTextField", dessen className ich zur Identifizierung benötige.

    Die in "" genannten Namen sind die automatisch vergebenen IDs, nur das dazu am Ende noch eine automatisch vergebene Zahl kommt, also bspw. "contentBox1", "contentBoxBody5" oder "contentTextField21".

    Die Aufgabe, vor der ich bislang kapitulieren musste, ist nun, aus einer beliebig langen Liste von "contentBoxen" im "boxContainer" diejenige herauszufinden, deren "contentTextField" einen bestimmten className hat, anhand dessen ich den Inhalt der Box und damit die Box selbst identifizieren kann.

    Folgendes habe ich bislang versucht:

    var textNodes=boxContainer.getElementsByTagName("P");  
    var z;  
    for(z=0;z<textNodes.length;z++){  
    var textNodeNames=textNodes[z].className;}  
    alert(textNodeNames);
    

    Auf die Art bekomme ich aber nur den Namen des "contentTextField"s der "contentBox", die gerade geöffnet, also auf display:block gesetzt ist, was so ziemlich die einzige Box ist, deren Identifikation ich NICHT benötige! :D

    Die Frage ist nun, wie komme ich an die <p> Elemente der <div> Elemente der <div> Boxen, die auf display:none gesetzt sind?

    Am besten, ohne jede einzelne Box manuell auseinandernehmen zu müssen...?!?

    Falls jemand die Antwort hat und sie mich wissen lässt, sei ihm (oder ihr) mein Dank sicher! ;)

    Beste Grüße,

    Roadster.

    1. Aloha ;)

      Hmm, ich hoffe, ich verstehe dein Problem richtig. Falls ja, sollte das helfen:

      function getContentBoxByClassname(boxcontainer,classname) {  
        
          var paragraphs = boxcontainer.getElementsByTagName('p');  
        
          //Wir brauchen einen regulären Ausdruck, der auf den classname hört  
          var rex = new RegExp("\\b"+classname+"\\b");  
        
          for (var z = 0; z < paragraphs.length; z++) {  
        
              //Wenn das p-Element tatsächlich ein contentTextField ist  
              if (paragraphs[z].id.substring(0,16) == "contentTextField") {  
        
                  //und der className passt  
                  if ( paragraphs[z].className.search(rex) != -1) {  
        
                      //dann haben wirs gefunden -> gebe also boxcontainer zurück  
                      //finde also den boxcontainer  
                      var ret = paragraphs[z].parentNode;  
        
                      while (ret.id.substring(0,10) != 'contentBox') {  
        
                           //Zur Sicherheit mit Abbruchbedingung  
                           if (ret.tagName != 'BODY') {  
                               ret = ret.parentNode;  
                           else {  
                               ret = false;  
                               break;  
                           }  
        
                      }  
        
                      //und gib ihn zurück  
                      return ret;  
               }  
          }  
        
          //falls gar nix da war  
          return false;  
        
      }
      

      Falls nein, dann müsstest du mir sagen, was an meinem Verständnis deines Problems nicht deinem Problem entspricht ;)

      P.S.: Ich habe die Funktion gleich möglichst allgemein gehalten... Nicht, dass eine kleine Umstrukturierung in deinem DOM gleich dazu führt, dass die Funktion nicht mehr läuft.

      P.P.S.: Selbstverständlich und wie (fast) immer nicht getestet ;)

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
      ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
      1. Aloha ;)

        Hallo RIDER :)

        Habe deinen Code leider trotz Hinzufügens der fehlenden Klammer nicht richtig zum laufen gebracht: Hat mir immer "false" ausgespuckt! :(

        Aber habe (zumindest sieht es so aus) einen Weg gefunden! :)

        Folgenden:

        (actualContentBoxName ist der automatisch eingefügte className; der Code steht in meinem ebenso automatisch mit jeder neuen Box in der Ablage hinzugefügten "click"-eventListener)

        var openTextNodes=boxContainer.getElementsByTagName("P");  
        var txt="";  
        var z;  
        for(z=0;z<openTextNodes.length;z++){  
        openTextNodeName=txt+openTextNodes[z].className;  
        if(openTextNodeName==actualContentBoxName){alert(openTextNodeName);}  
        else{}
        

        ...spuckt mir tatsächlich immer den gesuchten, zur jeweiligen "link"-Box bzw. Ablagebox dazugehörigen className aus, wenn ich auf selbige Ablage-Boxen clicke - und wenn DAS geht, dann sollte auch der Rest kein (großes) Problem sein! ;)

        Es geht halt darum, dass, wie ich in einem anderen Post erwähnte, ja eine Ablage-Funktion eingebaut habe (wobei es den "Behalten"-Button nicht mehr gibt --> statt dessen landet die contentBox, wenn sie nicht per "Schließen"-Button geschlossen wurde, direkt in der Ablage, wenn eine neue contentBox geöffnet wird, sprich es ist immer nur eine contentBox geöffnet --> alles andere ist mir mit zuviel Scrollen verbunden!).

        Das heißt, wenn ich durch click auf einen Menüpunkt eine neue "contentBox" öffne (erschaffe), ohne vorher die offene Box regulär geschlossen zu haben, wird die bereits offene Box ausgeblendet und auf display:none gesetzt und auf meinem "stack" unterhalb des Menüs eine "link-Box" bzw. Ablagebox mit dem Titel der gerade geschlossenen Box eingeblendet.

        Wird eine Box regulär per "Schließen"-Button geschlossen, wird die Box komplett gekillt, - wenn sie nur "verdrängt" wird, dann ist sie weiter im boxContainer vorhanden, nur halt auf display:none und kann (bislang: "sollte") per click auf die entsprechende "link"-Box unterhalb des Menüs wieder geöffnet werden, wobei dann die link-Box wiederum gekillt wird und die jetzt offene Box auf display:none gesetzt und ihre zugehörige "link"-Box auf den stack gelegt wird.

        Ich weiß, ich weiß, sehr verwirrend! :D

        Die Funktion zu schreiben, dass das alles vollautomatisiert abläuft ohne sich in die Quere zu kommen war ein Alptraum! Ohne dich hätte wäre ich wohl noch Weihnachten damit beschäftigt! ;)

        Zum besseren Verständnis mal ein Bild von der Front:

        http://www.directupload.net/file/d/3832/wfkj37s2_jpg.htm

        Habe nacheinander die §§1 bis 4 aus dem Menü geöffnet, ohne die contentBoxen per "Schließen"-Button geschlossen (und damit gelöscht) zu haben.

        Wenn ich jetzt unter dem Menü auf - sagen wir "AGG §2" - clicke, wird erstmal die offene Box, also "AGG §4" ausgeblendet und auf display:none gesetzt, dann wird auf dem Stapel unter dem Menü eine neue Box draufgepackt "AGG §4", und anschließend wird (soll) dann die zu "AGG §2" gehörige "contentBox" wieder aus der Versenkung geholt und eingeblendet werden, wobei dann die "AGG §2" Box wiederum aus der Ablage verschwindet.

        Ein sehr praktisches Feature!!! :D

        Vor allem, wenn man bedenkt, dass der "stack" ja "offen für alles" ist, sprich nicht an irgendeine Ansicht oder eine Kategorie gebunden. --> Da kann ich jede beliebige Ansicht meiner Seite zwischenspeichern, egal aus welchem Gebiet oder ob es sich dabei um Dokumente oder Funktionsansichten handelt! :)

        Vielleicht bekomme ich deinen Code ja doch noch zum laufen, in jedem Fall vielen, vielen Dank für die Mühe!!!

        Beste Grüße,

        Roadster.

        1. Ahoi RIDER :)

          Also, dein Code schaut ungemein elegant aus, aber ich bekomme es irgendwie nicht gebacken. :(

          Jedenfalls funktioniert mein folgendes Konstrukt:
          (Verbesserungsvorschläge sind natürlich willkommen!)

          function findContentBox(){  
          var boxContainer=document.getElementById("boxContainer");  
          var boxContainerTextNodes=boxContainer.getElementsByTagName("P");  
          var txt="";  
          var z;  
          for(z=0;z<boxContainerTextNodes.length;z++){  
          boxContainerTextNodeNames=txt+boxContainerTextNodes[z].className;  
          if(boxContainerTextNodeNames==wantedContentBoxName){ // variable aus parent-function übernommen  
          var wantedElementClassName=boxContainerTextNodeNames;}  
          else{}}  
          var wantedElementClassNameList=document.getElementsByClassName(wantedElementClassName);  
          var k;  
          for(k=0;k<wantedElementClassNameList.length;k++){  
          var wantedElementId=txt+wantedElementClassNameList[k].id;}  
          var wantedElement=document.getElementById(wantedElementId);  
          var wantedBoxBodyId=wantedElement.parentNode.id;  
          var wantedBoxBody=document.getElementById(wantedBoxBodyId);  
          var wantedContentBoxId=wantedBoxBody.parentNode.id;  
            
          var wantedContentBox=document.getElementById(wantedContentBoxId); //got it! :)  
            
          alert(wantedContentBoxId);}
          

          Etwas klobig halt, das. :)

          PS: Vielleicht behalte (sic!) ich den "Behalten"-Button doch - nur genau umgekehrt, als ursprünglich geplant, also nicht, um contentBoxen auf den stack zu legen, sondern um sie genau davor zu bewahren. Sollen die Leute doch selbst entscheiden, ob sie die einzelnen Dokumente und Ansichten hintereinanderweg dargestellt haben wollen, oder ob sie es wie ich komfortabler finden, über die Ablage zwischen den Ansichten zu switchen. Man könnte dann ja auch beide Funktionsweisen nach belieben kombinieren. Würde die Benutzbarkeit sicher nicht verschlechtern! Hmm... mal sehen! ;)

          Auf jeden Fall nochmal danke!

          Beste Grüße,

          Roadster.

          1. Aloha ;)

            Also, dein Code schaut ungemein elegant aus, aber ich bekomme es irgendwie nicht gebacken. :(

            Ich hab mir schnell auf JSFiddle ein Minimalbeispiel gebaut, die Klammerfehler aus meinem Beispiel (mea culpa) korrigiert und lasse dann Testweise nach der contentBox mit contentTextField-Klasse "Klasse2" suchen, um diese dann hellblau einzufärben.

            Hat funktioniert ;)

            Vielleicht hattest du die Klammerfehler i-wie falsch korrigiert?

            Es kann aber natürlich immer noch sein, dass meine Lösung an deinem Problem vorbeigeht, weil ich das Problem noch nicht en detail verstanden habe. Ich würde dir also empfehlen: Schau mal mein Beispiel an und vergleiche es mit deiner Situation. Wenn dir auffällt, was du anders brauchst, sag Bescheid und ich schreibs dir dementsprechend um.

            Grüße,

            RIDER

            P.S.: Was mir erst im Nachhinein kam: Die Methode wird noch ein wenig schlanker, wenn man die neue Funktion querySelector einsetzt... Ich habe die JSFiddle mal geforked mit dem schlankeren Ansatz. Hat den Vorteil, dass da gänzlich auch reguläre Ausdrücke verzichtet werden kann.

            --
            Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
            ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
          2. Aloha ;)

            Zusätzlich zu meinem eben geposteten, funktionierenden Beispiel...

            (Verbesserungsvorschläge sind natürlich willkommen!)

            Na, dann leg ich mal los mit dem advocatus diaboli :D

            var txt="";

            Bislang noch sinnlos, oder? Soll da später noch was rein?

            var z;
            for(z=0;z<boxContainerTextNodes.length;z++){

            Du kannst die Variable z auch direkt in der for-Schleife "declaren". also for(var z = 0; ...
            Spart dir eine Zeile Code ;) Jede unnötige, eingesparte Zeile dient der Codeleserlichkeit ;)

            boxContainerTextNodeNames=txt+boxContainerTextNodes[z].className;

            Vorsicht. Bedenke: className ist die Liste aller Klassennamen, also eventuell nicht ausschließlich oder exklusiv die Zeichenkette, auf die du...

            if(boxContainerTextNodeNames==wantedContentBoxName){ // variable aus parent-function übernommen

            ...hier prüfen willst. Da brauchst du schon (einfache) reguläre Ausdrücke dafür. (Oder eben die querySelect-Funktion) Wir wollen ja nicht, dass dein System zusammenklappt und sofort, sobald du dich irgendwann entscheidest, den p's eine weitere Klasse zu geben.

            var wantedElementClassName=boxContainerTextNodeNames;}

            Bin ich jetzt blöd oder hättest du statt der Anweisung und der darüber auch einfach schreiben können var wantedElementClassName=wantedContentBoxName; ?

            else{}}

            unschön ;) Else ohne Inhalt. Trägt nicht zur Leserlichkeit bei. Außerdem hoffe ich, dass du in deinem Arbeitscode die Einrückung mehr beherzigst als hier in dem, was du postest ;)

            var wantedElementClassNameList=document.getElementsByClassName(wantedElementClassName);

            ah, mir war entgangen, dass es document.getElementsByClassName inzwischen auch so gibt. Das ist dann natürlich neben RegExp und querySelect die dritte Möglchkeit, sicher nach Klassen zu selektieren...

            var k;
            for(k=0;k<wantedElementClassNameList.length;k++){
            var wantedElementId=txt+wantedElementClassNameList[k].id;}

            Statt dem hier hättest du einfach schreiben können: var wantedElementId=wantedElementClassNameList[(wantedElementClassNameList.length - 1)]; Die for-Schleife ist also irgendwie imho murks - die tut nämlich nix.

            var wantedContentBox=document.getElementById(wantedContentBoxId); //got it! :)

            Sicher, dass du hast was du wolltest? Für mich siehts eher so aus, als wenn du immer und grundsätzlich und auch unabhängig von den Klassen immer nur das letzte Element bekommst, das mit document.getElementsByClassName(wantedContentBoxName) ausgeliefert wird... Glaube kaum, dass das das erwünschte Verhalten ist ;)

            Ich will dich ja nicht in Stücke reden, aber der Code hier ist - zumindest glaube ich das - ziemlich untätiger Murks gewesen ;) Entschuldige mir den Ausdruck, nicht persönlich gemeint. Vielleicht ist da auch die U(h)rzeit dran schuld ;)

            PS: Vielleicht behalte (sic!) ich den "Behalten"-Button doch - nur genau umgekehrt, als ursprünglich geplant, also nicht, um contentBoxen auf den stack zu legen, sondern um sie genau davor zu bewahren. Sollen die Leute doch selbst entscheiden, ob sie die einzelnen Dokumente und Ansichten hintereinanderweg dargestellt haben wollen, oder ob sie es wie ich komfortabler finden, über die Ablage zwischen den Ansichten zu switchen. Man könnte dann ja auch beide Funktionsweisen nach belieben kombinieren. Würde die Benutzbarkeit sicher nicht verschlechtern! Hmm... mal sehen! ;)

            Aus meiner Sicht: dafür. Das "Behalten" ist ein Feature, welches der Nutzer als Zusatz bekommt - und manche finden das sicher intuitiver als das automatische Ablegen.

            Grüße,

            RIDER

            --
            Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
            ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
            1. Aloha ;)

              Hallo RIDER :)

              Zusätzlich zu meinem eben geposteten, funktionierenden Beispiel...

              Also ich habe mir deine beiden Beispiele nochmal vorgenommen!

              Beim ersten Beispiel kommt bei mir in der Web-Konsole (ohne Zeilenangabe)

              "TypeError: Property 'handleEvent' is not callable."

              und beim zweiten Beispiel wird in der Zeile

              var paragraphs = boxContainer.querySelectorAll('p.'+classname);

              "SyntaxError: An invalid or illegal string was specified"

              angemahnt. (Das mit dem 'box C ontainer' hab ich schon richtig deklariert...)

              Könnte es damit zu tun haben, dass du in deinen Beispielen bei den contentBoxen eine <div> Ebene ausgelassen hast, oder "finded" der code grds. alle <p> Elemente?

              Ist halt sehr kryptisch und ich versteh eigentlich nur Bahnhof! :)

              [Aber bevor du dich nochmal dransetzen würdest, falls du dies noch vorgehabt hättest, lies den Post bitte erst zuende!]

              So sollte der (virtuelle) HTML-Code für die Boxen aussehen:

              <div id="boxContainer">  
               <div id="contentBoxN">  
                <div id="contentBoxHeaderN">  
                 <div id="contentBoxHeadLineN">  
                 </div>  
                 <div id="contentBoxCloseButtonN">  
                  <p id="contentBoxCloseButtonTextN">  
                  </p>  
                 </div>  
                </div>  
                <div id="contentBoxBodyN">  
                 <p id="contentTextFieldN" class="boxName">  <!-- "boxName" brauche ich -->  
                 </p>  
                </div>  
               </div>  
              </div>
              

              Also: (boxContainer) > contentBox > contentBoxBody > contentTextField | (div) div div p.

              Sicher, dass du hast was du wolltest? Für mich siehts eher so aus, als wenn du immer und grundsätzlich und auch unabhängig von den Klassen immer nur das letzte Element bekommst, das mit document.getElementsByClassName(wantedContentBoxName) ausgeliefert wird... Glaube kaum, dass das das erwünschte Verhalten ist ;)

              Ehrlich, warum mein Code funktioniert kann ich auch nicht so genau sagen, aber er tut's! :D

              Kann fünf oder sechs Boxen in die Ablage laden und egal auf welche ich draufclicke wird per alert(wantedContentBoxId) tatsächlich immer genau der Name der dazugehörigen contentBox angezeigt. Habe auch mal kurz die Funktion mit dem reload der versteckten contentBoxen hinzugefügt und auch das hat ohne weiteres geklappt, egal welche Box im Ablagestapel ich angeclickt habe, er hat tatsächlich die dazugehörige contentBox wieder in den boxContainer geladen!

              Ich will dich ja nicht in Stücke reden, aber der Code hier ist - zumindest glaube ich das - ziemlich untätiger Murks gewesen ;) Entschuldige mir den Ausdruck, nicht persönlich gemeint. Vielleicht ist da auch die U(h)rzeit dran schuld ;)

              Ich bin der Letzte, der in Abrede stellen würde, dass mein Code Murks ist! :D
              Ist gewissermaßen mein Markenzeichen...und ja, bin seit ca. 36h non-stop vor statt in der Kiste! Unglaublich, wie schnell so eine 500g Packung Kaffepulver aufgebraucht ist! ;)

              Naja und was die Einrückungen angeht, das ist so eine Sache! Ich habe zwar einen recht großen Bildschirm, aber je weiter man den code auseinander schreibt, desto weniger kann man insgesamt im Blick behalten. Muss man abwägen! Ich finde es desto übersichtlicher, je mehr Code ich gleichzeitig überblicken kann. (Außerdem hat Notepad++ doch dieses schicke Feature die Klammern links am Rand nochmal in einer extra Leiste mit Knoten darzustellen...)

              Mir ist im Übrigen bei meiner geplanten Praxis noch ein unerwünschter Nebeneffekt aufgefallen:

              Die Reihenfolge der Boxen! Heiliger BimBam! Wenn ich das so umsetzen wollte, wie ich geplant hatte, mit 'Behalten' und so, dann würde das ein schlimmes Rumgehüpfe der contentBoxen ergeben! Oder ich müsste ziemlich aufwändig die Reihenfolge der contentBoxen im boxContainer steuern!

              Vielleicht wäre es ja eine insgesamt viel elegantere Lösung, statt die Boxen auf display:none zu setzten und von dort wieder aufzurufen, die Boxen wie beim "Schließen"-Button-Mechanismus komplett zu löschen, nur dass ich dabei einfach die Funktions-Parameter an die 'Link-Box' in der Ablage weitergebe, und von da aus die createNewContentBox-Funktion bei bedarf aufs Neue starte, so als hätte man den Link im Menü gedrückt!

              Dann bräuchte ich auch nur noch die ID von der Box die gerade angezeigt wird. [getAttribute("display")?]

              Ok, wenn ich das mit dem 'Behalten'-Button mit reinnehme, würde ich doch die Funktion brauchen, die IDs der contentBoxen im boxContainer zu ermitteln, denn dann wären es ja mehr als eine...

              Aber das hat jetzt im Moment eigentlich nicht sooo die Prioriät, wichtig ist erstmal, dass ich überhaupt einen funktionierenden Mechanismus habe (zumal ich die nächste Zeit sicher der einzige 'User' der Seite sein werde).

              Also ich werde mir jetzt erstmal eine große Kanne Kaffe aufsetzen, und dann schaue ich mir das alles nochmal genau an! ;)

              Nochmal vielen Dank und

              beste Grüße,

              Roadster.

            2. Hallo RIDER! :)

              Also ich hab die Steuerung schlussendlich doch noch hinbekommen wie ich es wollte, aber wow, das war echt der reinste brainfuck! :D

              Der Steuerungsmechanismus stellt ja schon für sich alleine genommen eine Knobelaufgabe dar, aber es kommen ja auch noch die Animationen zum Ein- und Ausblenden der Boxen dazu, bzw. dazwischen...

              Fünf Funktionen verteilt auf 223 Zeilen Code (ohne Einrückungen oder Zeilenabstände) - der reinste Alptraum! - Aber es läuft!

              Jetzt bleiben eigentlich nur noch zwei Fragen zu dem Thema, bei denen ich nicht so wirklich weiterkomme:

              1. Verzögerung der Funktionsausführung, solange Animation läuft

              Bislang hatte ich es auf der Seite immer so gehandhabt, dass ich vor jede Funktion, die mit einer laufenden Animation kollidieren könnte, einfach eine Bedingung gesetzt habe im Sinne von:

              element1.addEventListener("click",function(){  
              if((element2.style.animationPlayState=="running")  
              ||(element3.style.animationPlayState=="running")){}  
              else{ /* ... */ }});
              

              Das hat aber natürlich erstens den Nachteil, dass, wenn irgendwas läuft, eben beim Click auf das Element nichts passiert und man dann nochmal draufclicken muss, was irgendwie einen touch von "funktioniert nicht richtig" hat, und zweitens ist diese Art der Konfliktvermeidung wohl ziemlich unbrauchbar, wenn man keine statischen, in überschaubarer Menge vorliegenden, sondern wie ich hier in diesem Fall, unzählige dynamisch erstellte Elemente hat!

              Ich dachte daran, vieleicht dem "boxContainer", der ansich keine Klassenbezeichnung hat, mit jedem Animationsstart einen boxContainer.className="running" und mit jedem Animationsende einen boxContainer.className="clear" mit auf den Weg zu geben, und dann so etwas wie eine while-Schleife zu installieren, also while(boxContainer.className=="running"){} oder so, aber wie könnte ich das umsetzten? - Habe Angst davor, mit while herumzuexperimentieren, nachdem ich doch zuletzt meinen Browser damit schachmatt gesetzt habe! ;)

              2. Hüpfende Boxen in der Ablage

              Zwar habe ich es geschaft mit einer Manipulation von .insertBefore (dessen Spiegelfunktion wahrscheinlich aus sprachhygienischen Gründen nicht implementiert wurde...) dafür gesorgt, dass wenn man auf eine Box in der Ablage clickt und diese 'Ablagebox' dann ausgeblendet wird, selbige umgehend in der Ablage ans Ende gesetzt wird, aber natürlich hinterlässt sie beim Ausblenden eine Lücke, die dann von den anderen Boxen, die ggf. sich noch darunter befinden, eher ungeschmeidig geschlossen wird.

              Aber ich nehme an, da kann man nichts machen, abgesehen davon, jeder "Ablagebox" noch einen unsichtbaren Rahmen mitzugeben, den man dann mit CSS so animiert, dass er sich nach dem Ausblenden der "Ablagebox" langsam verkleinert... hmm...nochmehr Code! D:

              Tja mal sehen, aber falls du mir das mit der while-Schleife irgendwie idiotensicher verklickern könntest, wäre das der Wahnsinn! ;)

              Wie immer,

              Dank und Gruß,

              Roadster.

              1. Aloha ;)

                Fünf Funktionen verteilt auf 223 Zeilen Code (ohne Einrückungen oder Zeilenabstände) - der reinste Alptraum! - Aber es läuft!

                Mit Einrückungen wäre es sicher weniger Albtraum ;) Jedem so, wie er es will :D

                Jetzt bleiben eigentlich nur noch zwei Fragen zu dem Thema, bei denen ich nicht so wirklich weiterkomme:

                1. Verzögerung der Funktionsausführung, solange Animation läuft

                Bislang hatte ich es auf der Seite immer so gehandhabt, dass ich vor jede Funktion, die mit einer laufenden Animation kollidieren könnte, einfach eine Bedingung gesetzt habe im Sinne von:

                element1.addEventListener("click",function(){

                if((element2.style.animationPlayState=="running")
                ||(element3.style.animationPlayState=="running")){}
                else{ /* ... */ }});

                
                >   
                > Das hat aber natürlich erstens den Nachteil, dass, wenn irgendwas läuft, eben beim Click auf das Element nichts passiert und man dann nochmal draufclicken muss, was irgendwie einen touch von "funktioniert nicht richtig" hat, und zweitens ist diese Art der Konfliktvermeidung wohl ziemlich unbrauchbar, wenn man keine statischen, in überschaubarer Menge vorliegenden, sondern wie ich hier in diesem Fall, unzählige dynamisch erstellte Elemente hat!  
                  
                Ja, das stimmt. Das sollte nicht so sein. Besser: die erneute Auslösung der Funktion, die auf den klick (oder was auch immer) hört, per window.setTimeout nochmal nachschieben. Der User sollte (je nachdem wie lange es dauert bis dann was passiert) aber auch direkt eine visuelle Rückmeldung bekommen, dass seine Eingabe registriert und nur noch nicht abgearbeitet wurde - z.B. durch einen unstörend aufpoppenden Hinweistext.  
                  
                
                > Ich dachte daran, vieleicht dem "boxContainer", der ansich keine Klassenbezeichnung hat, mit jedem Animationsstart einen `boxContainer.className="running"`{:.language-javascript} und mit jedem Animationsende einen `boxContainer.className="clear"`{:.language-javascript} mit auf den Weg zu geben, und dann so etwas wie eine while-Schleife zu installieren, also `while(boxContainer.className=="running"){}`{:.language-javascript} oder so, aber wie könnte ich das umsetzten? - Habe Angst davor, mit `while`{:.language-javascript} herumzuexperimentieren, nachdem ich doch zuletzt meinen Browser damit schachmatt gesetzt habe! ;)  
                  
                Davon würde ich (in dem Fall) auf jeden Fall auch die Finger lassen. Nimm die nativ gegebenen Möglichkeiten (setTimeout, setInterval). Alles andere würde heißen, die Webseite und den Browser mit ihrer eigenen Rechenfähigkeit bewusst zum erliegen zu bringen.  
                  
                
                > 2. Hüpfende Boxen in der Ablage  
                >   
                > Aber ich nehme an, da kann man nichts machen, abgesehen davon, jeder "Ablagebox" noch einen unsichtbaren Rahmen mitzugeben, den man dann mit CSS so animiert, dass er sich nach dem Ausblenden der "Ablagebox" langsam verkleinert... hmm...nochmehr Code! D:  
                  
                Hätte ich intuitiv jetzt auch so gemacht. Vorschlag zur Güte: Statt die Box auszublenden und nen leeren Ramen dafür einzublenden: Lass doch einfach die vorhandene Box zuerst kleiner werden und blende sie dann endgültig aus. Spart auf jeden Fall Code, wahrscheinlich kannst du da an den meisten Stellen vorhandene Funktionalitäten einfach ausbauen.  
                  
                
                > Tja mal sehen, aber falls du mir das mit der while-Schleife irgendwie idiotensicher verklickern könntest, wäre das der Wahnsinn! ;)  
                  
                Idiotensicher und Wahnsinn schließt sich aus.  
                  
                Grüße,  
                  
                RIDER  
                  
                
                -- 
                Camping\_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller  
                  
                ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[