franc: onclick-Ereignis per Skript auslösen

Hallo,

wie kann ich per Skript im Firefox (mit Hilfe von Greasemonkey) ein onclick()-Ereignis eines Elementes auslösen?
Wenn ich es so versuche:

document.getElementById("my_id").onclick();

kriege ich einen Firefox-Fehler:

uncaught exception: [Exception... "Component is not available" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: file:///.../components/greasemonkey.js :: anonymous :: line 379" data: no]

Ich las bei:

http://developer.mozilla.org/en/XPCNativeWrapper#Limitations_of_XPCNativeWrapper

dass ich erst selbst einen Event-Handler für das Element einrichten muss:

var el = document.getElementById("my_id");
el.addEventListener("click", <function>, false);

aber wie kann ich jetzt die Funktion, die das Event auslösen soll, direkt beim registrieren des EventListeners schon auslösen?
Nämlich innerhalb EINER Funktion?

Das geht nicht:

el.addEventListener("click", function(){el.onclick();} , false);

das auch nicht:

el.addEventListener("click", this.onclick() , false);

Gibts da einen Trick?

Gruß franc

  1. Hi,

    aber wie kann ich jetzt die Funktion, die das Event auslösen soll, direkt beim registrieren des EventListeners schon auslösen?

    Suchst du vielleicht dispatchEvent?

    MfG ChrisB

    --
    „This is the author's opinion, not necessarily that of Starbucks.“
    1. Suchst du vielleicht dispatchEvent?

      Nein, das funktioniert nicht, ich muss das Event innerhalb einer Funktion auslösen und das klappt irgendwie nicht.

      Also z.B. so geht es leider nicht, aber so bräuchte ich es:

      <input type="button" onclick="function () { var evt = document.createEvent('MouseEvents'); evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); var cb = document.getElementById('anderer_button');  var canceled = !cb.dispatchEvent(evt); if(canceled) { alert('canceled'); } else { alert('not canceled');}}" value="Zweiten Button ausloesen">
      <br /><br />
      <input id="anderer_button"  type="button" onclick="alert('Wurde ausgeloest!');" value="Soll ausgeloest werden">

      1. Hi,

        Nein, das funktioniert nicht, ich muss das Event innerhalb einer Funktion auslösen und das klappt irgendwie nicht.

        Lese bitte augenblicklich in der Charta (die gelesen zu haben du mit dem Posten bestaetigt hast!) in den Tipps fuer Fragende nach, warum "klappt irgendwie nicht" Bloedsinn ist, mit dem hier niemand was anfangen kann.

        Also z.B. so geht es leider nicht, aber so bräuchte ich es:

        Sorry, damit kann ich nichts anfangen.

        Beschreibe bitte mal nachvollziehbar, was du *erreichen* willst.

        MfG ChrisB

        --
        „This is the author's opinion, not necessarily that of Starbucks.“
      2. Also gut.

        Ich möchte auf einer Seite mit Anmeldeformular mit Hilfe von Greasemonkey ein automatisches Login durchführen (Benutzer und Passwort automatisch eintragen). Über die in Firefox eingebaute AutoLogin-Funktion geht es leider nicht.

        Das Formular wird aber erst über einen Login-Button geladen, den man (manuell) betätigen muss, dann erst werden die Formularfelder sichtbar.

        Ich will daher, sobald die Seite mit dem Login-Button geladen ist, diesen betätigen. Sein onclick() Event auslösen.
        Das geht aber so nicht. Ich kann das Event nur mit Greasemonkey auslösen, wenn ich vorher einen EventHandler registriert habe. Sonst kriege ich einen Firefox-Fehler.
        Und das will mir nicht gelingen, weil ich das ganze in einer setTimeout-Funktion drin habe, die EventHandler-Funktion kann ich also nicht vorher deklarieren, bzw. sie ist in der setTimeout-Funktion dann nicht bekannt.

        Ich habe (s.o.) schon einiges probiert, aber weiss jetzt nicht weiter.

        Im Prinzip rufe ich in meinem Greasemonkey-Skript auf:

        setTimeout( function(){if-Abfragen, ob das Element schon geladen ist } )

        und da mit rein müsste meine EventHandler-Registrierung und aber auch gleich der Event-Aufruf.

        Wenn ich übrigens den Quelltext der Initialseite aufrufe finde ich nur jede Menge Javascript vor, aber kein html. Es wird also alles erst (schön mit Frames) erstellt, was die Sache verkompliziert.

        1. Hallo,

          Ich möchte auf einer Seite mit Anmeldeformular mit Hilfe von Greasemonkey ein automatisches Login durchführen (Benutzer und Passwort automatisch eintragen).

          Dann fülle Benutzer- und Passwort-Feld aus und rufe submit() des Formulars auf.

          Das Formular wird aber erst über einen Login-Button geladen, den man (manuell) betätigen muss, dann erst werden die Formularfelder sichtbar.

          Die Sichtbarkeit von Elementen kannst du mit CSS beeinflussen.
          Oder wird auch das HTML per XMLHttpRequest nachgeladen? Untersuche das mit Firebug.

          Ich will daher, sobald die Seite mit dem Login-Button geladen ist, diesen betätigen. Sein onclick() Event auslösen.

          Wahrscheinlich denkst du um drei Ecken und es geht einfacher, wenn du das Formular selbst einblendest, als wenn du irgendwelche synthetischen Events erzeugst.

          Alternativ könntest du das Event-Handling der Seite analysieren. Irgendwie muss ja der Event-Handler registriert werden. Wenn onclick des Buttons nicht existiert, weil addEventListener genutzt wurde, müsste es jedoch klappen Script, einen synthetischen Klick-Event zu erzeugen. Aber auch das ist um drei Ecken gedacht. Du kannst genauso schauen, welche Funktion beim Klick auf den besagten Button aufgerufen wird. Das wäre dann um zwei Ecken gedacht. Schließlich kannst du, siehe oben, direkt das Element einblenden, sofern wirklich nur das beim Klick auf den Button getan wird.

          Ich kann das Event nur mit Greasemonkey auslösen, wenn ich vorher einen EventHandler registriert habe. Sonst kriege ich einen Firefox-Fehler.

          Häh? Das verstehe ich nicht. Du musst keinen weiteren Event-Handler registrieren, um einen bestehenden auszulösen. Wie kommst du darauf?

          Du kannst die Eigenschaft onclick als Funktion natürlich erst aufrufen, nachdem sie vom Script der fremden Site gesetzt wurde (oder steht onclick direkt im HTML-Code?). Das passiert üblicherweise onload, also ggf. nachdem dein Greasemonkey-Script aktiv wird.

          Und das will mir nicht gelingen, weil ich das ganze in einer setTimeout-Funktion drin habe, die EventHandler-Funktion kann ich also nicht vorher deklarieren, bzw. sie ist in der setTimeout-Funktion dann nicht bekannt.

          Verstehe ich nicht.

          setTimeout( function(){if-Abfragen, ob das Element schon geladen ist } )

          und da mit rein müsste meine EventHandler-Registrierung und aber auch gleich der Event-Aufruf.

          Du zäumst das Pferd offenbar von hinten aus. Du solltest dir erst einmal ganz andere Fragen stellen: Wie und wann registriert die fremde Seite den Event-Handler, was tut die Handlerfunktion und was davon willst du imitieren? Ob das Element schon per DOM zur Verfügung steht, hat mit dem Event-Handling direkt nichts zu tun.

          Wenn ich übrigens den Quelltext der Initialseite aufrufe finde ich nur jede Menge Javascript vor, aber kein html.

          Dann musst du das analysieren! Firebug hilft dir dabei. Damit kannst du dir den DOM-Baum ansehen, Element-Eigenschaften und Haltepunkte im JavaScript setzen, sodass du genau die Ausführung des Scriptes beim Klick auf den Button verfolgen kannst.

          Mathias

          1. Ich kann das Event nur mit Greasemonkey auslösen, wenn ich vorher einen EventHandler registriert habe. Sonst kriege ich einen Firefox-Fehler.

            Häh? Das verstehe ich nicht. Du musst keinen weiteren Event-Handler registrieren, um einen bestehenden auszulösen. Wie kommst du darauf?

            Wenn ich das onclick Ereignis per Code auslösen will in Greasemonkey, löst das einen Fehler aus:
            uncaught exception: [Exception... "Component is not available" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: file:///.../components/greasemonkey.js :: anonymous :: line 379" data: no]

            Du kannst die Eigenschaft onclick als Funktion natürlich erst aufrufen, nachdem sie vom Script der fremden Site gesetzt wurde (oder steht onclick direkt im HTML-Code?).

            Genau. Hängt an einem DIV:
            <div id="idtxt1" class="link bold" onclick="doLogin()" onmouseout="colorChange(this)" onmouseover="colorChange(this)" title="Anmelden für Kunden">Login</div>

        2. Hi,

          Ich möchte auf einer Seite mit Anmeldeformular mit Hilfe von Greasemonkey ein automatisches Login durchführen (Benutzer und Passwort automatisch eintragen). Über die in Firefox eingebaute AutoLogin-Funktion geht es leider nicht.

          Das Formular wird aber erst über einen Login-Button geladen, den man (manuell) betätigen muss, dann erst werden die Formularfelder sichtbar.

          Brauchst du dieses Formular denn ueberhaupt?
          Wird da noch eine Session-ID o.ae. uebergeben, die du dir durch den Login-Button erst holen musst?

          Ich will daher, sobald die Seite mit dem Login-Button geladen ist, diesen betätigen. Sein onclick() Event auslösen.

          Wenn es sich um eine "statische" Seite handelt - kannst du dann nicht einfach nachschauen, welche JS-Funktion er aufruft, und diesen manuell aufrufen?

          Und das will mir nicht gelingen, weil ich das ganze in einer setTimeout-Funktion drin habe, die EventHandler-Funktion kann ich also nicht vorher deklarieren, bzw. sie ist in der setTimeout-Funktion dann nicht bekannt.

          Dann solltest du dich vielleicht ueber Closures informieren.

          Wenn ich übrigens den Quelltext der Initialseite aufrufe finde ich nur jede Menge Javascript vor, aber kein html. Es wird also alles erst (schön mit Frames) erstellt, was die Sache verkompliziert.

          "View Selection Source" zeigt dir den aktuellen "Quelltext" an, und auch ueber FireBug kannst du das aktuelle HTML bequem inspizieren.

          MfG ChrisB

          --
          „This is the author's opinion, not necessarily that of Starbucks.“
          1. Wird da noch eine Session-ID o.ae. uebergeben, die du dir durch den Login-Button erst holen musst?

            Ein Klick auf das Login-DIV ruft die Funktion doLogin() auf, darin steht:

            function doLogin() {
            top.body.location=strLogin+"?timestamp="+new Date().getTime();
            updateMenue('login');
            }

            Es wird also noch ein Timestamp übergeben.

            Wenn es sich um eine "statische" Seite handelt - kannst du dann nicht einfach nachschauen, welche JS-Funktion er aufruft, und diesen manuell aufrufen?

            doLogin finde ich aber nicht im Quelltext des Frames in dem das Login-DIV steht. Wenn ich auf der (Firebug-)Konsole doLogin() aufrufe kriege ich einen Fehler (nicht bekannt).
            Ich müsste wissen, wie ich eine Funktion in einem Frame aufrufen könnte.

            Dann solltest du dich vielleicht ueber Closures informieren.

            Das ist ganz schön komplex!

            "View Selection Source" zeigt dir den aktuellen "Quelltext" an, und auch ueber FireBug kannst du das aktuelle HTML bequem inspizieren.

            Das verwende ich schon.

            1. doLogin finde ich aber nicht im Quelltext des Frames in dem das Login-DIV steht.
              Ich müsste wissen, wie ich eine Funktion in einem Frame aufrufen könnte.

              Ausgehend vom obersten Frameset:
              window.frames.framename.funktion

              Siehe
              http://aktuell.de.selfhtml.org/artikel/javascript/fensterzugriff/
              http://de.selfhtml.org/javascript/objekte/frames.htm

              Aufrufen mit () dahinter. Wenn du diesen Ausdruck (ohne die Klammern) in die Firebug-Konsole eingibst und Enter drückst, kannst du das Funktionsobjekt anklicken, dann kommst du in den Code in die Zeile, in der die Funktion notiert wurde.
              Es kann natürlich sein, dass der Code "minified" wurde, also für dich schlecht lesbar ist. Dann schreibst du .toString() hinter besagten Ausdruck und jagst den ausgegebenen Code durch einen Beautifier.

              Mathias

              1. Ausgehend vom obersten Frameset:
                window.frames.framename.funktion

                Siehe
                http://aktuell.de.selfhtml.org/artikel/javascript/fensterzugriff/
                http://de.selfhtml.org/javascript/objekte/frames.htm

                Ah! Danke, das hatte ich gesucht.

                Aufrufen mit () dahinter. Wenn du diesen Ausdruck (ohne die Klammern) in die Firebug-Konsole eingibst und Enter drückst, kannst du das Funktionsobjekt anklicken, dann kommst du in den Code in die Zeile, in der die Funktion notiert wurde.
                Es kann natürlich sein, dass der Code "minified" wurde, also für dich schlecht lesbar ist. Dann schreibst du .toString() hinter besagten Ausdruck und jagst den ausgegebenen Code durch einen Beautifier.

                Danke für die guten Tipps. Firebug ist wirklich das Beste AddOn das es gibt!

                Es funktioniert jetzt mit:

                /servlet/P/SSA_MLS_PPP_PUBLIC_P/loginLogout.do

                das ist nämlich der Aufruf, den doLogin macht, plus Timestamp hintendran, brauchts aber nicht. Geht auch so.

                Gruß, franc

            2. Hi,

              Wird da noch eine Session-ID o.ae. uebergeben, die du dir durch den Login-Button erst holen musst?

              Ein Klick auf das Login-DIV ruft die Funktion doLogin() auf, darin steht:

              function doLogin() {
              top.body.location=strLogin+"?timestamp="+new Date().getTime();
              updateMenue('login');
              }

              Es wird also noch ein Timestamp übergeben.

              Ja und? Das kannst du doch genauso gut selber machen ...

              Finde erst mal heraus, was in strLogin steht.

              MfG ChrisB

              --
              „This is the author's opinion, not necessarily that of Starbucks.“
              1. Finde erst mal heraus, was in strLogin steht.

                Ah, jetzt habe ich im Firebug entdeckt, wie man an die anderen Javascripts rankommt. Über dem Skript-Tab ist nochmal ein (verstecktes) DropDown-Feld mit allen Skripten der Seite. Da hab ich dann endlich ein Breakpoint setzen können bei doLogin().
                Es steht darin:
                /servlet/P/SSA_MLS_PPP_PUBLIC_P/loginLogout.do

                Und wenn ich das direkt als Adresse eingebe GEHT ES!!!

                Danke für deine unermüdliche Zuarbeit!

                Gruß franc