Marvin Esse: per CSS oder javascript automatisch Code an div anhängen

Hallo,

ich nutze feste DIVs (die ID fängt immer mit "helper" an), die mit position:absolute und visibility:hidden initiiert werden und auf der Seite zum Einblenden von Informationen oder auch kleine Formulare genutzt werden. Der Inhalt der DIVs ändert sich also dynamisch abhängig vom Nutzerverhalten. Ich würde jetzt gerne quasi nachträglich an diese DIVs HTML-Code an die rechte Ecke anheften, z.B. in Form eines kleinen Bildes mit Link.

Wie kann ich das am Besten anstellen? Über CSS geht das wohl nicht, da content: nur Text enthalten kann und keine HTML-Markups? Wenn ich per Javascript ein weiteres Dummy-DIV erzeuge, wie kann ich dieses dann sicher immer an die rechte Ecke vom Helper-Div heften, da der Inhalt und damit die Größe des Helper-Divs immer variabel ist.

LG Marvin

  1. Hallo Marvin Esse,

    Wenn ich per Javascript ein weiteres Dummy-DIV erzeuge, wie kann ich dieses dann sicher immer an die rechte Ecke vom Helper-Div heften, da der Inhalt und damit die Größe des Helper-Divs immer variabel ist.

    Dieses Element erzeugst du als Kind des umgebenden divs und positionierst absolut mit top=0 und right=0. Div ist nicht passend, wenn du einen Link erzeugen möchtest. Ich würde das gleich in einem Abwasch mit dem Erzeugen der helper-divs erledigen.

    Bis demnächst
    Matthias

    --
    Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
    1. Hallo Matthias,

      Dieses Element erzeugst du als Kind des umgebenden divs und positionierst absolut mit top=0 und right=0. Div ist nicht passend, wenn du einen Link erzeugen möchtest. Ich würde das gleich in einem Abwasch mit dem Erzeugen der helper-divs erledigen.

      Ich habe das Bild jetzt in einem test wie folgt erzeugt:

      <style>
      #helper1 img {
      	position:absolute;
      	top: -10px;
      	left: calc(100% - 20px);
      }
      </style>
      
      	var image = document.createElement("img");
      	image.src = "info.gif";
      	image.id = "pic";
      	image.onclick = "test();";
      	r.appendChild(image);
      
      <div id="helper1">
      	Lorem ipsum ... blabla blabla<br/>
      	Lorem ipsum ... blabla blabla<br/>
      	Lorem ipsum ... blabla blabla<br/>
      </div>
      

      Zwei Probleme habe ich aber noch dabei:

      • Das Bild wird abgeschnitten, es soll sich aber ja anheften und überschneidend angezeigt werden
      • Die Funktion test() wird beim Klick auf das Bild nicht aufgerufen.

      LG Marvin

      1. Zwei Probleme habe ich aber noch dabei:

        • Das Bild wird abgeschnitten, es soll sich aber ja anheften und überschneidend angezeigt werden
        • Die Funktion test() wird beim Klick auf das Bild nicht aufgerufen.

        Problem 2 konnte ich schon lösen:

        image.onclick = function() { test(); };
        

        war des Rätsels Lösung ;-))

        LG Marvin

        1. Hallo Marvin

          Problem 2 konnte ich schon lösen:

          image.onclick = function() { test(); };
          

          Das wird vielleicht funktionieren, ist aber nicht wirklich sinnvoll. Wenn du die Funktion test als Eventhandler registrieren willst, dann kannst du das auch direkt tun, anstatt den Aufruf in einer anonymen Funktion zu kapseln.

          image.onclick = test;
          

          Beachte, dass hinter dem Funktionsbezeichner in diesem Fall keine Klammern notiert werden, denn du willst hier bloß ein Funktionsobjekt referenzieren, diese Funktion jedoch nicht gleich aufrufen. Der Aufruf soll schließlich erst erfolgen, wenn das Ereignis eingetreten ist.

          function test (event) {
            // do something
          }
          

          Abgesehen davon, dass bei dieser Variante ein Funktionsaufruf eingespart wird, gehen hierbei auch nicht die Informationen verloren, die über das Ereignisobjekt bereitgestellt werden, das einer als Eventhandler registrierten Funktion beim Aufruf als Argument übergeben wird.

          image.onclick = function (event) {
            // do something
          }
          

          Sofern die Funktion test ohnehin nur an dieser Stelle referenziert wird, kannst du die Funktion übrigens auch gleich bei der Zuweisung definieren, wie in dem Beispiel oben.


          Allerdings solltest du grundsätzlich die Methode addEventListener verwenden, um Funktionen als Eventhandler zu registrieren, was bezogen auf deinen Anwendungsfall so aussehen könnte:

          image.addEventListener('click', test);
          

          Auch hier kannst du dir gegebenenfalls die Vergabe eines Bezeichners sparen und die entsprechende Funktion direkt bei der Registrierung definieren:

          image.addEventListener('click', function (event) {
            // do something
          });
          

          Viele Grüße,

          Orlok

          1. @@Orlok

            image.onclick = function() { test(); };
            

            Das wird vielleicht funktionieren

            „Vielleicht“ im Sinne von: für einen eingeschränkten Kreis von Nutzern.

            ist aber nicht wirklich sinnvoll.

            Ist es nicht. Und das hat zunächst einmal nichts mit der rechten Seite vom Gleichheitszeichen zu tun, sondern mit der linken.

            LLAP 🖖

            --
            „Wenn du eine weise Antwort verlangst, musst du vernünftig fragen.“ —Johann Wolfgang von Goethe
          2. Hallo Orlok,

            image.onclick = function() { test(); };
            

            Das wird vielleicht funktionieren, ist aber nicht wirklich sinnvoll. Wenn du die Funktion test als Eventhandler registrieren willst, dann kannst du das auch direkt tun, anstatt den Aufruf in einer anonymen Funktion zu kapseln.

            image.onclick = test;
            

            Vielen Dank für die ausführliche Erklärung. Da die am Ende genutzte Funktion bereits existiert und in einer eigenen JS-Funktionen-Bibliothek ausgelagert ist, werde ich dann, wie empfohlen

            image.addEventListener('click', test);
            

            nutzen.

            LG Marvin

            1. @@Marvin Esse

              werde ich dann, wie empfohlen

              image.addEventListener('click', test);
              

              nutzen.

              Wenn du das nutzen wirst, ist das bedauerlich. Aber sage bitte nicht „wie empfohlen“ dazu!

              „Wie empfohlen“ heißt: keinen click-Handler fürs Bild zu verwenden.

              LLAP 🖖

              --
              „Wenn du eine weise Antwort verlangst, musst du vernünftig fragen.“ —Johann Wolfgang von Goethe
            2. Hallo Marvin

              Da die am Ende genutzte Funktion bereits existiert und in einer eigenen JS-Funktionen-Bibliothek ausgelagert ist, werde ich dann, wie empfohlen

              image.addEventListener('click', test);
              

              nutzen.

              Das wäre schlecht. Der Inhalt dieses Beitrags stellt nur einen Teil dessen dar, was hier im Thread als Empfehlung herausgelesen werden kann. Sprich es ging mir hier in erster Linie nur darum dir zu zeigen, wie du das mit der Ereignisbehandlung besser machen kannst.

              Wie Gunnar in diesem Beitrag erklärt hat ist es jedoch keine gute Idee, überhaupt einen Eventhandler für das Image-Element zu registrieren, und das ist der andere und wichtigere Teil der Empfehlung, den du berücksichtigen solltest!

              Wenn wir also mal annehmen, dass eine andere Aktion ausgelöst werden soll als der Sprung zu einer anderen Ressource oder einer anderen Stelle im selben Dokument – für den ein Link völlig ausreichend wäre, dann wäre wie Gunnar sagte das Image-Element in einen Button zu packen und für diesen Button ein Eventhandler zu registrieren.

              button.addEventListener('click', handler);
              

              Die Funktion handler würde dann nicht nur bei einem Klick auf den Button selbst, sondern auch bei einem Klick auf dessen Kindelement, also das Image-Element, aufgerufen, und das Ganze wäre obendrein mit der Tastatur bedienbar. – Und somit für manche Benutzergruppen überhaupt erst zugänglich.

              Also bitte denk noch einmal darüber nach, was hier für dich die beste Vorgehensweise ist.

              Viele Grüße,

              Orlok

        2. Jein. Mit image.onclick=function(evt) { ... }; kannst Du zurechtkommen, es kann Dir aber dann auf die Füße fallen wenn sich noch jemand auf das Event registrieren will.

          Deswegen ist bei Event-Fragen jener hier dein Freund, es sei denn, du willst den IE mit Version < 9 unterstützen, dann ist es etwas aufwändiger.

          var imageClicked = function(eventObj) {
             // do something
          };
          image.addEventListener('click', imageClicked);
          

          Innerhalb der Eventhandler-Funktion zeigt this auf das DOM Element, das das Event ausgelöst hat, also das Image, und du bekommst ein MouseEvent übergeben. Also alles wie bei onclick=function(evt){...}, mit dem Unterschied, dass Du mit addEventListener mehr als einen Listener für ein Event registrieren kannst.

          Wenn Du die Funktion nicht deregistrieren können musst (removeEventHandler), dann kannst Du sie auch gleich inline als Parameter angeben und musst sie nicht in einer Variablen speichern. Also so:

          image.addEventListener('click', function(eventObj) {
             // do something
          });
          

          Rolf

          1. Hallo Rolf

            Innerhalb der Eventhandler-Funktion zeigt this auf das DOM Element, das das Event ausgelöst hat

            Eventhandler werden grundsätzlich im Kontext des Elementes aufgerufen, für das der Handler registriert wurde. Dabei kann es sich wie in deinem Beispiel um das Element handeln, welches das Ereignis ausgelöst hat, aber das muss nicht so sein.

            Wenn ich also explizit das Element referenzieren möchte, für das der jeweilige Handler registriert wurde, dann kann ich das über this machen, oder aber über die Eigenschaft currentTarget des Ereignisobjektes, welche ebenfalls eine Referenz auf dieses Element enthält.

            Letzteres ist ein wenig mehr Schreibarbeit, verbessert meiner Meinung nach aber die Lesbarkeit des Codes, insbesondere dann, wenn die als Handler registrierte Funktion nicht unmittelbar bei der Registrierung definiert wird.

            Wenn es andererseits darum geht das Element zu referenzieren, welches das Ereignis ausgelöst hat, beziehungsweise welches das Ziel des Ereignisses auf seinem Weg durch das DOM ist, dann wäre dies über die Eigenschaft target des Ereignisobjektes zu bewerkstelligen.

            document.body.addEventListener('click', function (event) {
              console.log(event.target.tagName);
            });
            

            Abgesehen davon, dass man in vielen Fällen die Ereignisbehandlung an ein Element delegieren möchte, welches in der Hierarchie des DOM ein wenig höher angesiedelt ist, und der Zugriff auf das Element bei dem das Ereignis eingetreten ist somit ohnehin über die Eigenschaft target erfolgen muss, denke ich dass es allgemein zu empfehlen ist, das ereignisauslösende Element über diese Eigenschaft zu referenzieren. Selbst dann, wenn dieses Element keine Kindelemente besitzt und der Handler auch für dieses Element registriert wurde.

            Viele Grüße,

            Orlok

      2. @@Marvin Esse

        	var image = document.createElement("img");
        	image.src = "info.gif";
        	image.id = "pic";
        	image.onclick = "test();";
        	r.appendChild(image);
        

        Zwei Probleme habe ich aber noch dabei:

        Plus eins, was du noch gar nicht erkannt hast.

        Ein img-Element (ohne map) ist nicht (von Haus aus) interaktiv bedienbar. Wenn du dem einen click-Eventhandler zuweist, vergisst du, dass Nutzer deine Seiten auch anders nutzen als mit Mäusen. Navigation mit der Tastatur beispielsweise. Man könnte das img-Element so nachrüsten, dass es auch mit der Tastatur anwählbar ist und auch dass Screenreader-Nutzern dessen Funktion mitgeteilt wird – das wäre aber aufwendig.

        Sinnvoller ist es, die im Browser bereits vorhandenen Möglichkeiten zu nutzen und die von HTML dafür vorgesehenen Elemente zu nutzen:

        • Wenn das Bild eine Aktion auf der Seite auslösen soll, dann gehört es in ein button-Element. Diesem kannst du dann einen click-Eventhandler zuweisen.

        • Wenn das Bild ein Link zu einer anderen Ressource (bzw. einer anderen Stelle im aktuellen Dokument) sein soll, dann gehört es in ein a-Element. Das Linkziel steht im href-Attribut, JavaScript ist nicht erforderlich.

        image.onclick ist nicht zielführend.

        LLAP 🖖

        PS: `image.onclick`{: .language-js.block.bad style="display: inline"} – Kann ich darauf stolz sein, wie ich den Bugs im Forum-Stylesheet ein Schnippchen schlage?

        --
        „Wenn du eine weise Antwort verlangst, musst du vernünftig fragen.“ —Johann Wolfgang von Goethe
        1. @@Gunnar Bittersmann

          PS: `image.onclick`{: .language-js.block.bad style="display: inline"} – Kann ich darauf stolz sein, wie ich den Bugs im Forum-Stylesheet ein Schnippchen schlage?

          Sicher nicht. Aber vielleicht darauf, ein Ticket erstellt zu haben? ;-)

          LLAP 🖖

          --
          „Wenn du eine weise Antwort verlangst, musst du vernünftig fragen.“ —Johann Wolfgang von Goethe
  2. Hallo

    Wenn ich per Javascript ein weiteres Dummy-DIV erzeuge, wie kann ich dieses dann sicher immer an die rechte Ecke vom Helper-Div heften, da der Inhalt und damit die Größe des Helper-Divs immer variabel ist.

    Vergiss im ersten Schritt (die rechte Ecke). Du willst das div an die richtige Stelle im HTML-Markup einbauen. Dazu hängst du es mit JavaScript als Kind seines Elternelements in das DOM ein. Das war Schritt 1. An welcher Stelle es dargestellt wird, regelst du wiederum mit CSS. Über einen geeigneten Selektor sprichst du das Element an und vergibst die CSS-Regeln.

    Beispiel:

    <!-- HTML vor dem Eingriff -->
    <section>
     <h2>Bla</h2>
     <p>Blubb</p>
    </section>
    
    <!-- HTML nach dem Eingriff -->
    <section>
     <h2>Bla<img /></h2>
     <p>Blubb</p>
    </section>
    
    /* CSS */
    section h2 {
      position: relative;
    }
    section h2 img {
      position: absolute;
      right: 0;
      top: 0;
    }
    

    Die CSS-Regeln schlummern in der CSS-Datei und der zweite Block wird solange nicht benutzt, wie es keine Bilder in Überschriften der zweiten Klasse in Sektionen gibt. Wahrscheinlich wirst du mit IDs und/oder mit Klassen arbeiten müssen, um nicht ungewollt andere, gleichartig aufgebaute Elementgruppen zu beeinflussen.. Der erste Block für die Überschrift selbst legt eine Positionierung relativ zur Normalposition mit position: static; (Standardwert) fest, was ohne Angaben zu top, right, bottom oder left keinerlei Änderung der Position bewirkt. Für Kindelemente wird so aber der Bezugsrahmen (alle Werte beziehen sich auf den Kontext der Überschrift) festgelegt.

    Werden aber in die Überschrift Bilder eingefügt, wird dafür der zweite Block, der deren Position festlegt, benutzt. Da das Elternelement als Bezugsrahmen für die Positionierungsangaben des Bildes herhält, klebt das Bild mit top: 0; und right: 0; in der rechten oberen Ecke der Überschrift.

    Was den JavaScript-Teil betrifft, sind hier andere auskunftsfähiger als ich.

    Tschö, Auge

    --
    Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
    Toller Dampf voraus von Terry Pratchett
  3. Hallo,

    ich nutze feste DIVs (die ID fängt immer mit "helper" an), die mit position:absolute und visibility:hidden initiiert werden und auf der Seite zum Einblenden von Informationen oder auch kleine Formulare genutzt werden. Der Inhalt der DIVs ändert sich also dynamisch abhängig vom Nutzerverhalten. Ich würde jetzt gerne quasi nachträglich an diese DIVs HTML-Code an die rechte Ecke anheften, z.B. in Form eines kleinen Bildes mit Link.

    Würd' ich alles über Templates+Platzhalter erledigen, Beispiel ist verlinkt, da sind 3 div's die je nach Zustand der Anwendung mit dem entsprechenden Template bestückt werden. Also kein Gefummel mit display:none und so sondern einfach nur $('#out').html(template); (template vorher gerendert).pl