sariman: Geklickten Link feststellen und dessen Target herausfinden

Hallo an alle,

ich arbeite an einem Firefox-Plugin und muss eine Funktion schreiben, die die Zieladresse eines Links herausfindet und an den Server weiterleitet. Das muss aber so funktionieren, dass man mit der rechten Maustaste auf einem Link vom right click context menu die funktion bookmark() aufruft und dann das Target des Links weitergeleitet wird. Genauso wie bei "delicious" (Bookmarking-Plugin). Dabei habe ich zwei Probleme:

  1. Ich weiß nicht welcher Link vom Benutzer geklickt wird. Dieses Problem kann ich nicht durch html lösen, so dass ich jeden Link auf der Seite mit der Funktion bookmark() versehen kann. Denn das muss auf jeder beliebigen Seite (z.Bsp. yahoo, youtube usw.) funktionieren und nicht auf einer von mir erstellten Webseite.

  2. Außerdem weiß ich nicht, wie man unterscheidet, ob der Benutzer die Funktion bookmark() auf einem Link mit der rechten Maustaste aufgerufen hat oder einfach durch den Plugin-Button (es gibt nämlich so einen Button, der auch die bookmark() funktion aufruft) die aktuelle URL bookmarken will.

Ich hoffe, ich hab mein Problem klar genug darstellen können. Ich freue mich auf jegliche Hilfe.

  1. ich arbeite an einem Firefox-Plugin und muss eine Funktion schreiben,

    Was meinst du mit Plugin? Ein Firefox AddOn?

    1. Ich weiß nicht welcher Link vom Benutzer geklickt wird. Dieses Problem kann ich nicht durch html lösen, so dass ich jeden Link auf der Seite mit der Funktion bookmark() versehen kann. Denn das muss auf jeder beliebigen Seite (z.Bsp. yahoo, youtube usw.) funktionieren und nicht auf einer von mir erstellten Webseite.

    Das sollte mit einem AddOn kein Problem darstellen, woran bist du gescheitert?

    1. Außerdem weiß ich nicht, wie man unterscheidet, ob der Benutzer die Funktion bookmark() auf einem Link mit der rechten Maustaste aufgerufen hat oder einfach durch den Plugin-Button (es gibt nämlich so einen Button, der auch die bookmark() funktion aufruft) die aktuelle URL bookmarken will.

    Das Eventobjekt das bei jedem Klick übergeben wird bietet dir dich all diese Informationen an, was fehlt noch?

    Struppi.

    1. Ok, ich muss die Sache wohl etwas klarer darstellen. Zu ersten Frage "ja", ich meinte ein AddOn. Ich dachte beides laufen auf das gleiche hinaus. Anscheinend tun sie's nicht.

      Das erste Problem war und immernoch ist, dass ich nicht festellen kann, welchen Link der Benutzer gerade geklickt, oder besser gesagt auf welchem Link er die Funktion bookmark() aufgerufen hat. Mit "document.links" kann ich alle Links von einer Seite auflisten und deren Ziele sehen. Aber genau den ausgewählten Link herausfinden und drauf reagieren ist mir ein Rätsel.

      Und mit dem Eventobjekt kenne ich mich nicht so aus. Ich bin ganz neu in Webprogrammiererwelt und mit js hab ich auch nicht viel Erfahrung. Sagt mir etwa dieses Objekt, dass der Benutzer meine Funktion auf genau einem bestimmten Link aufgerufen hat? oder einfach im Freien Feld auf der Seite geklickt hat?

      Schon mal danke für das Lesen und Beantworten

      1. Hallo sariman,

        hier mal ein Beispiel, wie du per Eventhandler auf Elementattribute zugreifen kannst:

         ...  
        <script type="text/javascript">
        
        window.onload = function() {        // erst wenn das Dokument geladen ist  
         var links = document.getElementsByTagName("a");  // Kollektion aller Links im Dokument  
         for(var i=0;i<links.length;i++) {  
           links[i].onclick = function() {  // Jeder Link bekommt ein "onclick"  
             alert(this.href);              // Zugrriff auf die Attribute über "this"  
             return false;                  // Damit das Linkziel nicht verfolgt wird, sonst return true  
           }  
         }  
        }
        
        </script>  
          
        </head>  
        <body>  
          
        <p><a href="test.html">Klick</a> <a href="test1.html">Klick</a> <a href="test2.html">Klick</a> <a href="test3.html">Klick</a></p>  
          
        </body>
        

        Im Beispiel erhalten nach dem Laden der Seite (window.onload) alle Links (bzw. alle A-Tags) einen onclick-Eventhandler, in dem über this auf das Attribut href zugegriffen wird. Die Eventhandler habe ich als anonyme Funktionen, also Funktionen ohne Namen notiert. Dieses geht über

        xxx.onyyy = function() { ... }.

        Du kannst aber auch

        var handler = function() { ... }
          xxx.onyyy = handler ; // ohne "()"

        schreiben.

        Mehr hierzu findest du im Javascriptkapitel von selfhtml.

        Gruß, Jürgen

        1. hier mal ein Beispiel, wie du per Eventhandler auf Elementattribute zugreifen kannst:

          Es wäre viel einfacher den klick auf dem Dokument abzufangen und anhand des Event Objektes herauszufinden ob der Klick auf einem Link stattgefunden hat.

          Struppi.

          1. Hallo Struppi,

            Es wäre viel einfacher den klick auf dem Dokument abzufangen und anhand des Event Objektes herauszufinden ob der Klick auf einem Link stattgefunden hat.

            für einen Anfänger? Vieleicht hast du ja ein Beispiel dazu.

            Gruß, Jürgen

            1. Es wäre viel einfacher den klick auf dem Dokument abzufangen und anhand des Event Objektes herauszufinden ob der Klick auf einem Link stattgefunden hat.

              für einen Anfänger? Vieleicht hast du ja ein Beispiel dazu.

              Wieso Anfänger? Er will ein AddOn schreiben, das habe ich noch nie gemacht.
              Ein Beispiel sollte vom OP kommen, er will ja geholfen bekommen, aber na gut, weil es ein 3 Zeiler ist.

              window.document.onclick = function(e) {  
              if(!e) e = window.event;  
              var obj = e.target || e.srcElement;  
              if(obj.tagName && obj.tagName.toUpperCase() == 'A') return !!alert('ein Link');  
              };  
              
              

              Struppi.

              1. Hallo Struppi,

                return !!alert('ein Link');

                abenteuerliche Konstruktion :)

                Ich finde, jetzt ist dieser Thread eine runde Sache fürs Archiv und würdig, zitiert zu werden.

                Gruß, Jürgen

                1. return !!alert('ein Link');

                  abenteuerliche Konstruktion :)

                  Wieso? Das ist ein Testcase und dummerweise führte der Link in meinem lokalen Testdokument noch einen externen Link aus, daher war die Meldung nicht zu lesen, also musste der click ein false zurückgeben. alert() gibt undefined zurück und !!undefined  ist gleich false.

                  Nur damit der OP nicht von diesem Verhalten überrascht wird und nicht erkennt, was hier passiert.

                  Struppi.

                  1. Hallo Struppi,

                    Wieso? ...

                    ich fnde die "Abkürzung" von

                    alert("...); return false;

                    nach

                    return !!alert("...);

                    eben abenteuerlich. Aber andererseits zeigt sie, das Javascript in Sachen "Übersichtliche Konstrukte" eben doch sehr "C-ähnlich" ist, nach den Motto "Kurz und elegant geht über alles."

                    Gruß, Jürgen

                    1. Wieso? ...

                      ich fnde die "Abkürzung" von

                      alert("...); return false;

                      Naja, es sollte eigentlich eine Abkürzung sein, ich wollte nur eine Klammerung vermeiden.

                      nach

                      return !!alert("...);

                      eben abenteuerlich.

                      Ich halte das nicht für abenteuerlich, mit dem doppelten not-operator erzwingt  man einfach eine Umwandlung in einen boolschen Wert, was in C meines Wissens so nicht geht

                      Struppi.

                      1. Hallo Struppi,

                        Ich halte das nicht für abenteuerlich, mit dem doppelten not-operator erzwingt  man einfach eine Umwandlung in einen boolschen Wert, was in C meines Wissens so nicht geht

                        stimmt. In einigen Bereichen hat Javascript seinen (Groß-)Vater C bei weitem übertroffen. :)

                        Gruß, Jürgen

                        1. Ich halte das nicht für abenteuerlich, mit dem doppelten not-operator erzwingt  man einfach eine Umwandlung in einen boolschen Wert, was in C meines Wissens so nicht geht

                          stimmt. In einigen Bereichen hat Javascript seinen (Groß-)Vater C bei weitem übertroffen. :)

                          Hmm, irgendwie spüre ich immer noch etwas unverständnis ;-)

                          !!alert(); kann man doch Prima lesen: not not alert() und man weiß sofort was der Autor will, einen boolschen Wert. Es ist die Abkürzung für:
                          alert() ? true : false

                          Natürlich hab ich mich beim ersten lesen auch darüber gewundert, aber mittlerweile halte ich es für praktisch und einfacher zu lesen.

                          Struppi.

                          1. Hallo Struppi,

                            Hmm, irgendwie spüre ich immer noch etwas unverständnis ;-)

                            ich habe die Schreibweise schon verstanden.

                            !!alert(); kann man doch Prima lesen: not not alert() und man weiß sofort was der Autor will, ...

                            kein kein Alarm, also doch einer? *g*

                            ... einen boolschen Wert. Es ist die Abkürzung für:
                            alert() ? true : false

                            Schön kryptisch.

                            Natürlich hab ich mich beim ersten lesen auch darüber gewundert, ...

                            und genau das meine ich, man wundert sich bzw. fragt sich, was soll das. Gleiches gilt auch für Konstrukte mit ? und :, nach Möglichkeit noch tief verschachtelt, oder Shiften statt Multiplikation mit zwei, oder ganze Programme im Kopf einer for-Schleife, ... . C und an C angelehnte Sprachen lassen so etwas ja zu. Aber hier geht Eleganz vor Lesbarkeit. Einem Gerücht zu Folge soll ja ein Entwicklungsziel bei C die Unlesbarkeit gewesen sein. Und das habe ich mit "abenteuerlich" gemeint. Was aber nicht heißt, dass ich so etwas nicht mache.

                            Gruß, Jürgen

                            PS Auch sehr schön:

                            ( function() {  
                             alert("Hallo!");  
                            })();
                            
                            1. Yerf!

                              Einem Gerücht zu Folge soll ja ein Entwicklungsziel bei C die Unlesbarkeit gewesen sein.

                              Eigentlich eher die Kompaktheit (die Computer auf denen C entwickelt und eingesetzt wurde hatten recht wenig Arbeitsspeicher), allerdings ergibt sich meist das eine aus dem anderen...

                              Gruß,

                              Harlequin

                              --
                              <!--[if IE]>This page is best viewed with a webbrowser. Get one today!<![endif]-->
                            2. Hmm, irgendwie spüre ich immer noch etwas unverständnis ;-)

                              ich habe die Schreibweise schon verstanden.

                              War mir schon klar, ich meinte unverständnis eher im Sinn von nicht anwenden würden.

                              !!alert(); kann man doch Prima lesen: not not alert() und man weiß sofort was der Autor will, ...

                              kein kein Alarm, also doch einer? *g*

                              genau :-)
                              Aber na gut, das alert war ja nur drin wegen dem OP, ist kein gutes Beispiel.

                              ... einen boolschen Wert. Es ist die Abkürzung für:
                              alert() ? true : false

                              Schön kryptisch.

                              Finde ich nicht, aber...

                              Gleiches gilt auch für Konstrukte mit ? und :, nach Möglichkeit noch tief verschachtelt,

                              würde ich natürlich vermeiden. Ansonsten halte ich den Operator für praktisch und verständlich.

                              PS Auch sehr schön:

                              ( function() {

                              alert("Hallo!");
                              })();

                                
                              Mittlerweile Standard, ich hab hier grad einen Entwurf rumliegen der macht es so:  
                                
                              ~~~javascript
                              var eineFunktion = (function() {  
                                 // tu_was ganz privates  
                                 return function(){  
                                    // zugreifen auf lokale Funktionen und Objekte  
                                 };  
                              })();  
                              
                              

                              Aber sowas braucht man halt, weil das Kapselungsvermögen von JS nicht besonders ist.

                              Struppi.

                        2. stimmt. In einigen Bereichen hat Javascript seinen (Groß-)Vater C bei weitem übertroffen. :)

                          Naja, was Javascript von C geerbt hat, ist die Syntax und einiges an Unsinn. ;-)

                          --
                          Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
                          Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|
              2. Es wäre viel einfacher den klick auf dem Dokument abzufangen und anhand des Event Objektes herauszufinden ob der Klick auf einem Link stattgefunden hat.

                window.document.onclick = function(e) {

                if(!e) e = window.event;
                var obj = e.target || e.srcElement;
                if(obj.tagName && obj.tagName.toUpperCase() == 'A') return !!alert('ein Link');
                };

                
                >   
                > Struppi.  
                  
                diese Variante erkennt wirklich den Link und verfolgt das Linkziel auch nicht. Schön und gut. Das tut sie aber nur wenn man den Link klickt. Ich darf aber den Link nicht anfassen. Denn ich hab in meinem xul (Beschreibungssprache für Firefox AddOns) sowas stehen:  
                  
                ~~~xml
                  
                <popup id="contentAreaContextMenu">  
                 <menuitem id="rightclick" label="&cm-entry;" accesskey="B"  
                 insertafter="context-stop" oncommand="booklink();"/>  
                </popup>  
                
                

                Diese zwei Zeilen fügen dem Kontexmenü einen Eintrag hinzu, der dann etwa so ausschauen wird: "Bookmark this link". Wenn der Benutzer mit der rechten Maustaste den Kontextmenü öffnet und diesen Eintrag auswählt, wird die bookmark() aufgerufen. Und die schaut (verienfacht) so aus:

                  
                function bookmark()  
                {  
                  macheRequest('http://eineWebSeite/server/addBookmark?url=' + getURL());  
                  
                }  
                
                

                Ich tue eigentlich nichts anderes als bookmarken, aber statt das lokal auf dem Rechner zu speichern, schicke ich die URL an den Server. Ich muss also nur feststellen können, ob der Mauszeiger auf einem Link war, als die Methode bookmark() aufgerufen wurde. Wenn nicht, hole ich einfach die aktuelle URL, die im Adressfeld des Browsers steht. Wenn ja, dann hole ich die Zieladresse des Links. Ganz wie bei del.icio.us. Das ist aber anscheinend komplizierter als ich dachte

                1. <popup id="contentAreaContextMenu">
                  <menuitem id="rightclick" label="&cm-entry;" accesskey="B"
                  insertafter="context-stop" oncommand="booklink();"/>
                  </popup>

                    
                  booklink()  
                    
                  
                  >   
                  > ~~~javascript
                    
                  
                  > function bookmark()  
                  > {  
                  >   macheRequest('http://eineWebSeite/server/addBookmark?url=' + getURL());  
                  >   
                  > }  
                  > 
                  
                  

                  = bookmark()

                  Dass die Funktion oben in xul booklink() und unten in js bookmark() heißt, ist nur ein Schreibfehler. Beim Testen hatte ich nur eine andere Funktion (booklink) geschrieben, die den gleichen Inhalt wie bookmark() hat. Daran liegt's also nicht

                2. <popup id="contentAreaContextMenu">
                  <menuitem id="rightclick" label="&cm-entry;" accesskey="B"
                  insertafter="context-stop" oncommand="booklink();"/>
                  </popup>

                    
                  Vermutlich hast du im oncommand-Handler Zugriff auf ein Event-Objekt und über this Zugriff auf das geklickte Menuitem oder das geklickte HTML-Element.  
                    
                  Versuche  
                  booklink(event, this)  
                  und schaue, was in den ersten beiden Parametern ankommt.  
                    
                  Ansonsten frage mal in einer Gruppe, die sich speziell um FF-Addon-Entwicklung dreht.  
                    
                  Mathias
                  
                  -- 
                  [JavaScript-Erweiterung für das SELFHTML-Forum](http://forum.de.selfhtml.org/js/doku/)
                  
                  1. Vermutlich hast du im oncommand-Handler Zugriff auf ein Event-Objekt und über this Zugriff auf das geklickte Menuitem oder das geklickte HTML-Element.

                    Versuche
                    booklink(event, this)
                    und schaue, was in den ersten beiden Parametern ankommt.

                    Das war ein hilfreicher Vorschlag. Ich hab's auch gemacht und folgendes bekommen:

                    event: [object XULCommandEvent]
                    this: [object XULElement]

                    Das geht wohl über javascript-Grenzen hinaus. Ich schau mal auf XUL-Seiten rein.

                    Danke an alle für die Hinweise