Kann ich jquery click () aufrufen, um einem <a> -Link zu folgen, wenn ich noch keinen Ereignishandler mit bind oder click daran gebunden habe?

175

Ich habe einen Timer in meinem JavaScript, der das Klicken auf einen Link emulieren muss, um nach Ablauf der Zeit zu einer anderen Seite zu gelangen. Dazu benutze ich die click()Funktion von jQuery . Ich habe $().trigger()und window.locationauch verwendet, und ich kann es mit allen drei wie beabsichtigt funktionieren lassen.

Ich habe ein seltsames Verhalten beobachtet click()und versuche zu verstehen, was passiert und warum.

Ich verwende Firefox für alles, was ich in dieser Frage beschreibe, aber ich bin auch daran interessiert, was andere Browser damit machen werden.

Wenn ich keinen Ereignishandler verwendet $('a').bind('click',fn)oder $('a').click(fn)festgelegt habe, $('a').click()scheint der Aufruf überhaupt nichts zu bewirken. Der Standardhandler des Browsers für dieses Ereignis wird nicht aufgerufen, da der Browser die neue Seite nicht lädt.

Wenn ich jedoch zuerst einen Ereignishandler festlege, funktioniert er wie erwartet, auch wenn der Ereignishandler nichts tut.

$('a').click(function(){return true;}).click();

Dadurch wird die neue Seite geladen, als hätte ich selbst auf das a geklickt.

Meine Frage ist also zweifach: Ist das ein seltsames Verhalten, weil ich irgendwo etwas falsch mache? und warum macht das Aufrufen click()nichts mit dem Standardverhalten, wenn ich keinen eigenen Handler erstellt habe?

BEARBEITEN:

Wie Hoffman feststellte, als er versuchte, meine Ergebnisse zu duplizieren, passiert das oben beschriebene Ergebnis nicht wirklich. Ich bin mir nicht sicher, was die Ereignisse verursacht hat, die ich gestern beobachtet habe, aber ich bin mir heute sicher, dass es nicht das war, was ich in der Frage beschrieben habe.

Die Antwort lautet also, dass Sie keine Klicks im Browser "fälschen" können und dass jQuery lediglich Ihren Event-Handler aufruft. Sie können immer noch verwenden window.location, um die Seite zu wechseln, und das funktioniert gut für mich.

Mnebuerquo
quelle
2
Könnte
Sukrit Chhabra

Antworten:

90

Interessant ist, dass dies wahrscheinlich eine "Feature-Anfrage" (dh ein Fehler) für jQuery ist. Das jQuery-Klickereignis löst nur dann die Klickaktion (im DOM als onClick-Ereignis bezeichnet) für das Element aus, wenn Sie ein jQuery-Ereignis an das Element binden. Sie sollten zu jQuery-Mailinglisten ( http://forum.jquery.com/ ) gehen und dies melden. Dies könnte das gewünschte Verhalten sein, aber ich denke nicht.

BEARBEITEN:

Ich habe einige Tests durchgeführt und das, was Sie gesagt haben, ist falsch. Selbst wenn Sie eine Funktion an ein 'a'-Tag binden, gelangen Sie trotzdem nicht zu der durch das href-Attribut angegebenen Website. Versuchen Sie den folgenden Code:

<html>
<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
 <script>
  $(document).ready(function() {
   /* Try to dis-comment this:
   $('#a').click(function () {
    alert('jQuery.click()');
    return true;
   });
   */
  });
  function button_onClick() {
   $('#a').click();
  }
  function a_onClick() {
   alert('a_onClick');
  }
 </script>

</head>
<body>
 <input type="button" onclick="button_onClick()">
 <br>
 <a id='a' href='http://www.google.com' onClick="a_onClick()"> aaa </a>

</body>
</html> 

Es geht nie zu google.com, es sei denn, Sie klicken direkt auf den Link (mit oder ohne den kommentierten Code). Beachten Sie auch, dass das Klickereignis, selbst wenn Sie es an den Link binden, nach dem Klicken auf die Schaltfläche nicht lila wird. Es wird nur lila, wenn Sie direkt auf den Link klicken.

Ich habe einige Nachforschungen angestellt und es scheint, dass der .click nicht mit 'a'-Tags funktioniert, da der Browser das "falsche Klicken" mit Javascript nicht unterstützt. Ich meine, Sie können kein Element mit Javascript "anklicken". Mit 'a'-Tags können Sie das onClick-Ereignis auslösen, aber der Link ändert seine Farben nicht (in der Farbe des besuchten Links ist die Standardeinstellung in den meisten Browsern lila). Es wäre also nicht sinnvoll, das Ereignis $ (). Click mit 'a'-Tags arbeiten zu lassen, da das Aufrufen des href-Attributs nicht Teil des onClick-Ereignisses ist, sondern im Browser fest codiert ist.

Hoffmann
quelle
7
Ich habe Ihren Code ausprobiert und er funktioniert genau so, wie Sie es gesagt haben, aber mein Code funktioniert wie oben beschrieben. Ich werde noch einige Experimente durchführen und sehen, ob ich ein einfaches Beispiel für meine Ergebnisse zusammenstellen kann, das Sie ausprobieren können.
Mnebuerquo
1
OK. Es muss etwas gewesen sein, was ich falsch gemacht habe. Ich war mir zu dem Zeitpunkt, als ich meine Frage stellte, absolut sicher, dass es funktioniert, aber seit ich Ihr Beispiel ausprobiert habe, funktioniert meine nicht mehr. Ich werde einfach wieder zu window.location zurückkehren, um die Seite zu ändern, und nicht versuchen, den Klick vorzutäuschen.
Mnebuerquo
In der Tat ist click () nicht dazu gedacht, gefälschte Klicks zu erzeugen, aber manchmal können wir damit auf Schaltflächen oder Formulare mit Javascript-Injektionen klicken oder einfach nur, um einen temporären Hotkey über vorhandenen Javascript-Funktionen zu erstellen.
Aero Wang
241

Eine andere Möglichkeit ist natürlich, nur Vanille-Javascript zu verwenden:

document.getElementById("a_link").click()
Peter
quelle
1
Dies funktioniert in Safari nicht und laut HTML-Spezifikation müssen nur Eingaben dies implementieren.
Jeremy Kauffman
4
Dang! Das funktioniert! Aber ich muss sagen, dass es nicht ganz "Vanille" -Javascript ist, da es ein JQuery-Element verwendet, also eine Art Vanille-JQuery-Javascript ... Es funktioniert in Firefox 24 und IE 10.
bgmCoder
@BGM, ok, aber das click () befindet sich nicht auf einem jquery-Element. Sie können es durch getElementById ("..") ersetzen. Klicken Sie auf ()
Peter
Wow Wounder voll, funktioniert wie ich erwartet hatte. +1 gegeben :). Für andere Benutzer können Sie auch Folgendes verwenden: var lnk = document.getElementById ("a_link"); if (lnk == null) {// mache etwas ....} else {lnk.click (); }
Iqbal
In verschiedenen Browsern getestet, können IE10 & Jquery 1.6.4 dies nicht verarbeiten.
Hannes Schneidermayer
65

Wenn Sie sich den Code für die $.clickFunktion ansehen, gibt es bestimmt eine bedingte Anweisung, die prüft, ob für das Element Listener für das clickEreignis registriert sind , bevor es fortfährt. Warum nicht einfach das hrefAttribut über den Link abrufen und die Seitenposition manuell ändern?

 window.location.href = $('a').attr('href');

BEARBEITEN: Hier ist, warum es nicht durch die triggerFunktion jQuery-Quelle für Version 1.3.2 klickt :

 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
    if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
        event.result = false;

    // Trigger the native events (except for clicks on links)
    if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
        this.triggered = true;
        try {
            elem[ type ]();
        // prevent IE from throwing an error for some hidden elements
        } catch (e) {}
    }

Nach dem Aufruf von Handlern (falls vorhanden) löst jQuery ein Ereignis für das Objekt aus. Es werden jedoch nur native Handler für Klickereignisse aufgerufen, wenn das Element kein Link ist. Ich denke, das wurde aus irgendeinem Grund absichtlich gemacht. Dies sollte jedoch zutreffen, unabhängig davon, ob ein Ereignishandler definiert ist oder nicht. Daher bin ich mir nicht sicher, warum in Ihrem Fall das Anhängen eines Ereignishandlers dazu führte, dass der native onClickHandler aufgerufen wurde. Sie müssen das tun, was ich getan habe, und die Ausführung durchlaufen, um zu sehen, wo sie aufgerufen wird.

Ryan Lynch
quelle
Ich kann auf jeden Fall window.location und die href verwenden, wie ich in der Frage erwähnt habe. Ich versuche zu verstehen, was in jquery click () passiert und was die beobachteten Ergebnisse verursacht.
Mnebuerquo
Ich habe meine Antwort bearbeitet, um zu zeigen, wo in der jQuery-Quelle $ .click () -Aufrufe für Links behandelt werden.
Ryan Lynch
2
window.location funktioniert, postet jedoch keinen HTTP-Referrer und unterbricht die Zurück-Schaltfläche.
Chase Seibert
5

Klickhandler für Ankertags sind ein Sonderfall in jQuery.

Ich denke, Sie könnten zwischen dem Onclick-Ereignis des Ankers (dem Browser bekannt) und dem Click-Ereignis des jQuery-Objekts verwechselt werden, das die Vorstellung des DOM vom Anker-Tag umschließt.

Sie können die jQuery 1.3.2-Quelle hier herunterladen .

Die relevanten Abschnitte der Quelle sind die Zeilen 2643-2645 (ich habe dies in mehrere Zeilen aufgeteilt, um das Verständnis zu erleichtern):

// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
if (
     (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && 
       elem["on"+type] && 
       elem["on"+type].apply( elem, data ) === false
   )
     event.result = false;
Marschall
quelle
5

JS / jQuery unterstützt nicht das Standardverhalten von Links, auf die programmgesteuert "geklickt" wurde.

Sie können ein Formular erstellen und abschicken. Auf diese Weise müssen Sie nicht window.locationoder verwenden window.open, die von Browsern häufig als unerwünschte Popups blockiert werden.

Dieses Skript verfügt über zwei verschiedene Methoden: eine, die versucht, drei neue Registerkarten / Fenster zu öffnen (es öffnet nur eine in IE und Chrome, weitere Informationen unten), und eine, die beim Klicken auf einen Link ein benutzerdefiniertes Ereignis auslöst.

Hier ist, wie:

HTML

<html>
<head>
    <script src="jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="script.js" type="text/javascript"></script>
</head>
<body>
    <button id="testbtn">Test</button><br><br>

    <a href="https://google.nl">GOOGLE</a><br>
    <a href="http://en.wikipedia.org/wiki/Main_Page">WIKI</a><br>
    <a href="https://stackoverflow.com/">SO</a>
</body>
</html>

jQuery (script.js)

$(function()
{ 
    // Try to open all 3 links by pressing the button
    // - Firefox opens all 3 links
    // - Chrome only opens 1 of them without popup warning
    // - IE only opens 1 of them WITH popup warning
    $("#testbtn").on("click", function()
    {
        $("a").each(function()
        {
            var form = $("<form></form>");
            form.attr(
            {
                id     : "formform",
                action : $(this).attr("href"),
                method : "GET",
                // Open in new window/tab
                target : "_blank"
            });

            $("body").append(form);
            $("#formform").submit();
            $("#formform").remove();
        });
    });

    // Or click the link and fire a custom event 
    // (open your own window without following the link itself)
    $("a").on("click", function()
    {
        var form = $("<form></form>");
        form.attr(
        {
            id     : "formform",
            // The location given in the link itself
            action : $(this).attr("href"), 
            method : "GET",
            // Open in new window/tab
            target : "_blank"              
        });

        $("body").append(form);
        $("#formform").submit();
        $("#formform").remove();

        // Prevent the link from opening normally
        return false;
    });

});

Was es tut, ist für jedes Linkelement:

  1. Erstellen Sie ein Formular
  2. Gib ihm Attribute
  3. Hängen Sie es an das DOM an, damit es eingereicht werden kann
  4. Senden Sie es
  5. Entfernen Sie das Formular aus dem DOM und entfernen Sie alle Spuren. * Fügen Sie böses Lachen ein. *

Jetzt wird eine neue Registerkarte / ein neues Fenster geladen "https://google.nl"(oder eine beliebige URL, ersetzen Sie sie einfach). Wenn Sie versuchen, mehr als ein Fenster auf diese Weise zu öffnen, erhalten Sie leider eine Popup blockedMeldungsleiste, wenn Sie versuchen, das zweite zu öffnen (das erste ist noch geöffnet).


Weitere Informationen darüber, wie ich zu dieser Methode gekommen bin, finden Sie hier:

Neues Fenster / Tab ohne Verwendung von window.openoder öffnenwindow.location.href

Richard de Wit
quelle
3

Lösen Sie ein Hyperlink-Element aus, das sich innerhalb des Elements befindet, mit dem Sie die jquery verbinden möchten .click ()

<div class="TopicControl">
    <div class="articleImage">
       <a href=""><img src="" alt=""></a>
    </div>
</div>

In Ihrem Skript verbinden Sie sich mit dem Hauptcontainer, für den das Klickereignis aktiviert werden soll. Anschließend verwenden Sie die Standard-Abfragemethode, um das Element (Typ, Klasse, ID) zu finden und den Klick auszulösen. Was passiert, ist, dass jquery eine rekursive Funktion eingibt, um den Klick auszulösen, und Sie die rekursive Funktion unterbrechen, indem Sie die Funktion 'e' und stopPropagation () verwenden und false zurückgeben, da Sie möchten, dass jquery nichts anderes tut, als den Link auszulösen.

$('.TopicControl').click(function (event) {
         $(this).find('a').click();
        event.stopPropagation();
        return false;
     });

Eine alternative Lösung besteht darin, die Behälter in das Element zu wickeln und sie als Behälter anstelle von zu platzieren. Stellen Sie die Bereiche so ein, dass der Block so angezeigt wird, dass er den w3c-Standards entspricht.

Paul Styles
quelle
3

Mit jQuery können Sie das jQuery-Objekt für dieses Element auswählen. Holen Sie sich dann das zugrunde liegende DOM-Element und rufen Sie seine click()Methode auf.

von id

$("#my-link").each(function (index) { $(this).get(0).click() });

Oder verwenden Sie jQuery, um auf eine Reihe von Links nach CSS-Klasse zu klicken

$(".my-link-class").each(function (index) { $(this).get(0).click() });
10GritSandpaper
quelle
2

Es tut nichts, weil keine Ereignisse an das Ereignis gebunden wurden. Wenn ich mich richtig erinnere, verwaltet jQuery eine eigene Liste von Ereignishandlern, die für Leistungszwecke und andere Zwecke an NodeLists gebunden sind.

JasonWyatt
quelle
2

Wenn Sie diese Funktion für einen Fall oder sehr wenige Fälle benötigen. (Ihre gesamte App benötigt diese Funktion nicht.) Ich würde jQuery lieber unverändert lassen (aus vielen Gründen, einschließlich der Möglichkeit, auf neuere Versionen, CDN usw. zu aktualisieren) und die folgende Problemumgehung haben:

// For modren Browsers
$(ele).trigger("click");

// Relaying on Paul Irish's conditional class names http://bit.ly/HWIpAp (via HTML5 Boilerplate http://bit.ly/HUzi3I) where each IE version gets a class of its Version
$("html.ie7").length && (function(){
    var eleOnClickattr = $(ele).attr("onclick") 
    eval(eleOnClickattr);
  })()
Adardesign
quelle
1

Verwenden Sie zum Öffnen des Hyperlinks auf derselben Registerkarte:

$(document).on('click', "a.classname", function() {
    var form = $("<form></form>");
    form.attr(
    {
        id     : "formid",
        action : $(this).attr("href"),
        method : "GET",
    });

    $("body").append(form);
    $("#formid").submit();
    $("#formid").remove();
    return false;
});
DHARMENDRA SINGH
quelle