Skeeve: Eventhandler per Javascript notieren, die 2te

Moin!

Durch den Thread Eventhandler per Javascript notieren kam ich auf den gloreichen(?) Gedanken, meine links anders zu setzen. Leider klappt es nicht so ganz und nun bitte ich um Tipps

Hier mal die Rahmenbedingungen:

  • Das ganze ist für eine Applikation die nur mit JS läuft und
  • nur für Mozille/Gecko Browser konzipiert ist

Das konkrete Problem, was ich lösen möchte ist folgendes:
Ich bekomme eine XHTML Seite die links der Form
  <a href="datei.html">Stichwort</a>
enthält. Diese Datei wird per XMLHttpRequest geladen und nachbearbeitet. Bisher so, daß der Link zu
  <a href="#" onclick="doLink(this, 'datei.html')">Stichwort</a>
wird. Da mir aber zu verstehen gegeben wurde, daß das nicht so fein sei, habe ich mir überlegt, daß daraus nun werden solle:
  <a href="datei.html" onclick="doLink()">Stichwort</a>
doLink ist dabei eine Funktion, die die angegebene Datei per XMLHttoRequest lädt und in einem div zur Anzeige bringt.

Dummerweise ist es aber nun so, daß der Klick auf den Link dazu führt, daß die Datei direkt ins Browserfenster geladen wird. Der onclick event Handler müßte, meine ich, als Ergebnis false liefern, damit der Link nicht ausgeführt wird. Allerdings ist mir nicht klar, wie ich das bewerkstelligen kann. ein "return false" am Ende von doLink reicht hier nicht.

Hat jemand den hifreichen Tipp oder Link für mich?

-- Skeeve

  1. ... Allerdings ist mir nicht klar, wie ich das bewerkstelligen kann. ein "return false" am Ende von doLink reicht hier nicht.

    Dann musst du natürlich auch onclick="return doLink()" notieren.

    Struppi.

    --
    Javascript ist toll (Perl auch!)
    1. Moin!

      Dann musst du natürlich auch onclick="return doLink()" notieren.

      Schon klar... Nur: Wie mache ich das per JS?
      Mein Code ist: a[i].onclick= doLink;
      denn so soll man das ja notieren (siehe den anderen Thread).

      Wenn ich es so mache, dann ist es keine Problem:
      a[i].setAttribute( 'onclick', 'return doLink()');

      Aber ich habe es so verstanden, daß das auch ungern gesehen wird.

      -- Skeeve

      1. Hell-O!

        Dann musst du natürlich auch onclick="return doLink()" notieren.
        Schon klar... Nur: Wie mache ich das per JS?
        Mein Code ist: a[i].onclick= doLink;

        Mit einer anonymen Funktion sollte es gehen:

        a[i].onclick = function() { return doLink(); }

        Siechfred

        --
        Ich bin strenggenommen auch nur interessierter Laie. (molily)
        Welcome To Carcass Cuntry || Steuerfreie Geburtsbeihilfen?  || RT 221 Erfurt-Altstadt i.V.
        1. Moin!

          Mit einer anonymen Funktion sollte es gehen:

          a[i].onclick = function() { return doLink(); }

          Nö... Tut nicht. Ist ja auch kein Wunder. Schließlich ist auch das wieder eine funktion. Wenn damit der onclick handler den Wert geliefert hötte, dann hätte es auch doLink getan. Ob die nun einen Namen hat oder nicht sollte unerheblich sein.

          Zudem würde mir das auch nicht gefallen, für jeden der X links eine neue (anonyme) Funktion zu spendieren.

          -- Skeeve

          1. Mit einer anonymen Funktion sollte es gehen:
            Nö... Tut nicht.

            Könntest du bitte eine konkrete Fehlerbeschreibung liefern?

            Ist ja auch kein Wunder.

            Oh doch, das ist es.

            Schließlich ist auch das wieder eine funktion. Wenn damit der onclick handler den Wert geliefert hötte, dann hätte es auch doLink getan. Ob die nun einen Namen hat oder nicht sollte unerheblich sein.

            Das ist ein kleiner, aber sehr gravierender Unterschied. Ich fürchte, dass du das Prinzip noch nicht richtig verstanden hast, deshalb mal ein kleines Beispiel:

            Javascript:

            function doLink(s) {  
              alert(s);  
              return false;  
            }  
              
            function addEventToLinks () {  
              var a = document.links;  
              for(i = a.length - 1; i>=0; i--) {  
                a[i].onclick = function() { return doLink(this.href) }  
              }  
            }  
              
            window.onload = addEventToLinks;
            

            Dazugehöriges HTML:

            <body>  
              <ul>  
                <li><a href='foo'>foo</a></li>  
                <li><a href='bar'>bar</a></li>  
                <li><a href='baz'>baz</a></li>  
                <li><a href='boo'>boo</a></li>  
              </ul>  
            </body>
            

            Die Schreibweise a[i].onclick = function() { ... } ist verkürzt für a[i].onclick = new Function(" ... "). Damit erzeugst du ein neues Funktionsobjekt und weist dem Eventhandler eine Referenz auf dieses zu. Nur weil du schreibst: myFunc = new Function("alert('Boo!')"); wird die Funktion nicht automatisch ausgeführt, sondern du musst sie explizit über myFunc() aufrufen. Und so ist es in obigem Beispiel: Die referenzierte Funktion wird aufgerufen, sobald das Ereignis "Mausklick" eintritt.

            Siechfred

            --
            Ich bin strenggenommen auch nur interessierter Laie. (molily)
            Welcome To Carcass Cuntry || Steuerfreie Geburtsbeihilfen?  || RT 221 Erfurt-Altstadt i.V.
            1. Moin!

              Könntest du bitte eine konkrete Fehlerbeschreibung liefern?

              Könnte ich.. Habe aber gerade anhand eines Beispiels, das ich mir zusammengestoppelt habe festgestellt, daß der Fehler wohl woanders liegen muß. Ich habe auch schon eine Idee.

              Was Deine Erklärung zu anonymen funktionen angeht: Das war mir schon klar. Nur ist mir nicht klar, warum der Rückgabewert einer anonymen Funktion anders behandelt werden sollte als derjenige einer nicht-anonymen.

              Meine Ergebnisse hier hatten bei mir den Verdacht nahegelegt, daß bei einem a[i].onclick= doLink; der Rückgabewert von doLink verloren geht. Wenn ich doLink nun in eine anonyme Funktion verpacke, warum sollte der Rückgabewert der anonymen nicht auch verloren gehen.

              Aber sei es drum: Ich denke, ich weiß wo der Fehler liegt und die Rückgabewerte scheinen nicht verloren zu gehen.

              Danke für Eure Hilfe und ich melde mich später mit der Auflösung des "Rätsels".

              -- Skeeve

              1. Danke für Eure Hilfe und ich melde mich später mit der Auflösung des "Rätsels".

                Da bin ich mal gespannt.

                Struppi.

                --
                Javascript ist toll (Perl auch!)
              2. Was Deine Erklärung zu anonymen funktionen angeht: Das war mir schon klar. Nur ist mir nicht klar, warum der Rückgabewert einer anonymen Funktion anders behandelt werden sollte als derjenige einer nicht-anonymen.

                Offensichtlich ist es dir trotzdem noch nicht klar. Eine Funktion gibt erst etwas zurück, wenn sie aufgerufen wird. Das Erzeugen einer anonymen Funktion ist nicht gleichbedeutend mit ihrer Ausführung. obj.onclick = myFunc weist dem Eventhandler eine Referenz auf die Funktion myFunc zu. obj.onclick = myFunc() führt myFunc aus und weist den Rückgabewert dem Eventhandler zu, dort ist er allerdings völlig nutzlos, weil ein Eventhandler auf diesem Wege eine Funktionsreferenz erwartet.

                Und das erreicht man via obj.onclick = new Function("...") (oder die alternative Schreibweise), weil der Objektkonstruktor genau das zurückgibt, was du brauchst: Eine Funktionsreferenz. Doch leider führt Javascript hier keinen Typenabgleich aus, sonst müsste es hier in allen Fällen, in denen einem Eventhandler keine Referenz zugewiesen wird, einen Fehler werfen.

                Siechfred

                --
                Ich bin strenggenommen auch nur interessierter Laie. (molily)
                Welcome To Carcass Cuntry || Steuerfreie Geburtsbeihilfen?  || RT 221 Erfurt-Altstadt i.V.
                1. Moin!

                  Offensichtlich ist es dir trotzdem noch nicht klar.

                  Scon, nur scheinen wir aneinander vorbei zu reden.

                  Eine Funktion gibt erst etwas zurück, wenn sie aufgerufen wird.

                  d'acore

                  Das Erzeugen einer anonymen Funktion ist nicht gleichbedeutend mit ihrer Ausführung.

                  d'acore

                  obj.onclick = myFunc weist dem Eventhandler eine Referenz auf die Funktion myFunc zu.

                  d'acore. Und das ist das, was ich mit a[i].onclick= doLink; ja mache.

                  obj.onclick = myFunc() führt myFunc aus

                  d'acore, mache ich aber nicht.

                  Hier noch mal beide Varianten:

                    
                  function doLink() { ... return false; }  
                    
                  // mein  
                  a[i].onClick= doLink; // doLink wird erst beim Klick ausgeführt.  
                  // Dein  
                  a[i].onClick= function() {  
                    return doLink();  
                  } // die Anonyme und damit doLink wird erst beim Klick ausgeführt.  
                  
                  

                  Oder sehe ich da immer noch falsch?

                  -- Skeeve

                  1. a[i].onClick= doLink; // doLink wird erst beim Klick ausgeführt.

                    Ja, allerdings ist diese Zuweisung parameterfeindlich, denn sobald JS auf eine Klammer trifft, behandelt es doLink nicht mehr als Referenz, führt die Funktion aus und weist deren Rückgabewert dem Eventhandler onclick zu.

                    a[i].onClick= function() {
                      return doLink();
                    } // die Anonyme und damit doLink wird erst beim Klick ausgeführt.

                    Ja, so lange du keine Parameter übergeben willst, kommen deine und meine Variante auf's Gleiche raus. Erst wenn Parameter übergeben werden müssen, kommst du um die anonyme Funktion nicht herum (siehe mein erstes Beispiel).

                    Oder sehe ich da immer noch falsch?

                    Nee, aber irgendwie scheinen wir wirklich aneinander vorbeigeschrieben zu haben :-)

                    Siechfred

                    --
                    Ich bin strenggenommen auch nur interessierter Laie. (molily)
                    Welcome To Carcass Cuntry || Steuerfreie Geburtsbeihilfen?  || RT 221 Erfurt-Altstadt i.V.
                    1. a[i].onClick= doLink; // doLink wird erst beim Klick ausgeführt.

                      ...

                      a[i].onClick= function() {

                      und anzumerken sei hier noch, dass onClick nicht funktioniert.
                      JS ist nach wie vor casesensitive es heißt onclick.

                      Struppi.

                      --
                      Javascript ist toll (Perl auch!)
      2. Schon klar... Nur: Wie mache ich das per JS?
        Mein Code ist: a[i].onclick= doLink;

        Warum sagst du das nicht?
        Das ist was völlig anderes als HTML Code, den du uns vorher gezeigt hast.

        die Frage hier ist, warum du einen Link benutzt, wenn du gar nicht die Funktionalität eines Links haben willst?
        Also warum setzt du überhaupt einen Wert in href, wenn du nicht dahin willst.

        Struppi.

        --
        Javascript ist toll (Perl auch!)
        1. Moin!

          Warum sagst du das nicht?

          Ich war der Meinung ich hätte... Aber ich drücke mich wohl manchmal etwas ungeschickt aus.

          Das ist was völlig anderes als HTML Code, den du uns vorher gezeigt hast.

          Der HTML Code sollte das ergebnis sein.

          die Frage hier ist, warum du einen Link benutzt, wenn du gar nicht die Funktionalität eines Links haben willst?

          Weil ich (später) nicht die Eingabedatei, also die mit den Links, erstelle. Um es den Erstellern so einfach wie möglich zu machen, sollen die nur verwenden, womit sie umgehen können, und das ist nun mal ein href und kein onclick. Ich stehe auf dem Standpunkt, daß die Komplexität im Programm zu liegen hat und nicht vom Benutzer gefordert werden darf.

          Also warum setzt du überhaupt einen Wert in href, wenn du nicht dahin willst.

          Ich will schon da hin, aber eben nicht über den Link. Der Link würde das ganze ja im Fenster öffnen und nicht im div. Das ganze ist ein Hilfesystem mit 4 Bereichen:
          1. Div Logo
          2. Div Buchstaben Index (A...Z)
          3. Div Stichworte zum gewählten Buchstaben
          4. Div Hilfe zum Stichwort

          Konkret geht es hier um den 3. Div, der die bearbeiteten Links enthält und im 4. darstellen soll.

          -- Skeeve

          1. hi,

            Um es den Erstellern so einfach wie möglich zu machen, sollen die nur verwenden, womit sie umgehen können, und das ist nun mal ein href und kein onclick. Ich stehe auf dem Standpunkt, daß die Komplexität im Programm zu liegen hat und nicht vom Benutzer gefordert werden darf.

            Warum forderst du dann von ihnen, sowas "komplexes" wie HTML-Links zu liefern?

            Stelle ihnen doch eine Eingabemaske zur Verfügung, auf der sie die notwendigen Daten eingeben können.

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
          2. Das ist was völlig anderes als HTML Code, den du uns vorher gezeigt hast.

            Der HTML Code sollte das ergebnis sein.

            Was für eine Ergebnis?
            Du redest wirklich in Rätseln. Du willst einen JS Event setzen und keinen HMTL code erzeugen oder?

            die Frage hier ist, warum du einen Link benutzt, wenn du gar nicht die Funktionalität eines Links haben willst?

            Weil ich (später) nicht die Eingabedatei, also die mit den Links, erstelle. Um es den Erstellern so einfach wie möglich zu machen, sollen die nur verwenden, womit sie umgehen können, und das ist nun mal ein href und kein onclick. Ich stehe auf dem Standpunkt, daß die Komplexität im Programm zu liegen hat und nicht vom Benutzer gefordert werden darf.

            Da widerspreche ich dir nicht.

            Aber trotzallem verstehe ich nicht warum du es so machst wir du es machst.

            Was heißt, "Weil ich (später) nicht die Eingabedatei, also die mit den Links, erstelle."
            Das verstehe ich nicht bzw. in wlechem Zusammenhang diese aussage mit deiner Frage steht. Was willst du genau machen und was würdest du gern Wissen?

            Also warum setzt du überhaupt einen Wert in href, wenn du nicht dahin willst.

            Ich will schon da hin, aber eben nicht über den Link. Der Link würde das ganze ja im Fenster öffnen und nicht im div.

            Eben, du willst keinen Link, der eine URL öffnet, sondern eine x-belibigen Tag, der eine JS Funktion aufruft. Auch wenn du die funktionalität mit einem Link vergleichst ist es was anderes.

            Struppi.

            --
            Javascript ist toll (Perl auch!)
    2. Moin!

      Dann musst du natürlich auch onclick="return doLink()" notieren.

      Nachtrag: Auch das geht nicht, da ich dann "dolink(this)" schreiben muß. Aber (siehe die anderen Postings) das geht nicht per JavaScript zu setzen, wenn man nicht über setAttribute gehen will/soll.

      -- Skeeve

  2. Hallo Skeeve,

    <a href="datei.html" onclick="doLink()">Stichwort</a>

    ich bin mir jetzt nicht ganz sicher, aber versuch doch mal

    onclick="doLink();return false"

    oder

    onclick="return doLink()" mit return false in doLink.

    Gruß, Jürgen

  3. Moin!

    Vorweg kurz die Auflösung, warum es bei meinem Projekt mit "a[i].onclick= doLink;" nicht funktioniert: Ich serialisiere meine konvertierte Datei und weise sie per innerHTML den divs zu. Ein onclick Handler, der so gesetzt wurde, erscheint jedoch nicht im serialisierten Code.

    Jetzt lang den Hintergrund und um die offenen Fragen von Struppi und wahsaga zu beantworten.

    Ich bin im moment dabei die Online Hilfe einer Applikation zu überarbeiten. Die Hilfetexte und der Index werden/wurden von anderen erstellt die mit HTML (leidlich) umgehen können. Von daher mein Anspruch, href können die verwenden, onclick nicht.

    Für diese Hilfe wurden bisher frames verwendet, was ich auf divs umgestellt habe. Es wurde bisher benötigt:
    1. Eine HTML Datei für eine Liste der Anfangsbuchstaben der Stichworte.
    2. Eine HTML Datei für jeden Anfangsbuchstaben
    3. Eine HTML Datei für den vollständigen Index
    4. Eine HTML Datei für jedes Stichwort.

    1. und 2. habe ich gestrichen. Die generiere ich aus 3. mit JavaScript (zur Erinnerung: JS ist essentieller Bestandteil der Applikation. Ohne JS is nich)

    Wenn das Hilfefenster geladen wird, lade ich den Index per XMLHttpRequest nach. Anschließend bearbeite ich das Ergebnis indem jeder <a> einen onclick Handler erhält. Zudem wird die Liste der Anfangsbuchstaben (das 1. oben) generiert.

    Anschließend muß ich den Inhalt des <body> dieser Datei nehmen und zwischenspeichern. Außerdem wird der Inhalt per innerHTML in den div der Stichworte geschrieben. Durch passendes CSS sind zunächst alle Stichworte ausgeblendet.

    Wenn nun der Endbenutzer auf einen der Anfangsbuchstaben klickt, soll ihm eine Liste der Stichworte mit diesem Buchstaben angezeigt werden.

    Dies geschieht dadurch, daß ich in dem div der Stichworte dem div, das zu diesem Buchstaben gehört, eine Klasse verpasse, die ein "display:block" enthält. Damit erscheinen dann die Stichworte.

    Hinter jedem der Stichworte liegt dann der bearbeitete Link und der Klick darauf soll dann die zugehörige Datei in den div laden, der für die Hilfetexte zuständig ist.

    Das klappt jetzt alles so weit, allerdings nur, wenn ich mit setAttribute( 'onclick' ...) arbeite, da nur so auch wieder HTML generiert wird.

    Ich hatte mich schon mal daran versucht, mit DOM Manipulationen das ganze zu bewerkstelligen, bin aber kläglich gescheitert. Das würde jetzt aber zu weit führen.

    Danke für Eure Aufmerksamkeit ;-) Und ich hoffe, ich habe es einigermaßen verständlich machen können.

    -- Skeeve

    1. Wenn das Hilfefenster geladen wird, lade ich den Index per XMLHttpRequest nach. Anschließend bearbeite ich das Ergebnis indem jeder <a> einen onclick Handler erhält. Zudem wird die Liste der Anfangsbuchstaben (das 1. oben) generiert.

      Wenn du den Quelltext in das dokument schreibst (mit innerHTML) kannst du danch auf die entsprechenden A elemente zugreifen.

      In etwa so:

      var output = document.getElementById('out');
      output.innerHTML = xxxxx;

      var l = output.getElementsByTagName('a');
      for(var i = 0; i < l.length; i++)
      {
      l[i].onclick = function()
      {
      ....
      return false;
      }
      }

      Du könntest auch den href Wert löschen. Also ich seh das Problem nicht.

      Anschließend muß ich den Inhalt des <body> dieser Datei nehmen und zwischenspeichern. Außerdem wird der Inhalt per innerHTML in den div der Stichworte geschrieben. Durch passendes CSS sind zunächst alle Stichworte ausgeblendet.

      Wie gesagt eine andere Reihenfolge könnte deine Probleme schon verringern.

      Das klappt jetzt alles so weit, allerdings nur, wenn ich mit setAttribute( 'onclick' ...) arbeite, da nur so auch wieder HTML generiert wird.

      und das ist unnötig.

      Ich hatte mich schon mal daran versucht, mit DOM Manipulationen das ganze zu bewerkstelligen, bin aber kläglich gescheitert. Das würde jetzt aber zu weit führen.

      Solange das HTML nicht verabreitet ist nützen dir natürlich auch die DOM Funktionen nichts.

      Struppi.

      --
      Javascript ist toll (Perl auch!)
      1. Moin!

        Wie gesagt eine andere Reihenfolge könnte deine Probleme schon verringern.

        Gute Idee! Danke! Ich versuch es.

        -- Skeeve