web-dev-qa-db-de.com

Wie kann ich einen Klick auf ein Ankertag simulieren?

Ich möchte einen Klick auf ein Ankertag mit allen Extras simulieren, wie z. B. korrektes Zielhandling.

Es scheint eine "[click ()] [3]" -Methode für das DOM-Objekt von Anchor zu geben, aber nicht alle Browser unterstützen dies. Firefox wirft diesen Fehler aus:

Fehler: anchorObj.click ist keine Funktion

Es funktioniert auch seltsam bei Opera 10 und Konqueror, was unendliche Klicks verursacht, wenn es innerhalb eines Click-Handlers eines umgebenden div aufgerufen wird. Ich denke, nur IE8 funktioniert gut damit. Auf jeden Fall möchte ich es nicht, da große Browser meistens Probleme damit haben. 

Ich habe diese alternative Lösung für Firefox in Mozilla-Foren gefunden:

var evt = document.createEvent("MouseEvents"); 
evt.initMouseEvent("click", true, true, window, 
    0, 0, 0, 0, 0, false, false, false, false, 0, null); 
anchorObj.dispatchEvent(evt); 

Das erscheint mir zu hässlich und umständlich. Ich weiß nicht, wie kompatibel es ist, und ich möchte möglichst keinen browserspezifischen Code schreiben.

Ich kann location.href = anchorObj.href nicht verwenden. weil das Attribut "Ziel" nicht behandelt wird. Ich kann einige harte Kodierungen basierend auf dem Wert des Ziels durchführen, aber ich möchte auch das vermeiden.

Es wird vorgeschlagen, zu JQuery zu wechseln, aber ich bin mir nicht sicher, wie gut das Zielobjekt behandelt wird, da ich zuvor noch nicht damit gearbeitet habe.

45
Sedat Kapanoglu

Hier ist ein vollständiger Testfall, der das click-Ereignis simuliert, alle angehängten Handler (auch wenn sie angehängt wurden) aufruft, das "target"-Attribut ("srcElement" im IE) verwaltet, Blasen wie bei einem normalen Ereignis erzeugt und die Rekursionsverhinderung des IE emuliert. Getestet in FF 2, Chrome 2.0, Opera 9.10 und natürlich IE (6):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function fakeClick(event, anchorObj) {
  if (anchorObj.click) {
    anchorObj.click()
  } else if(document.createEvent) {
    if(event.target !== anchorObj) {
      var evt = document.createEvent("MouseEvents"); 
      evt.initMouseEvent("click", true, true, window, 
          0, 0, 0, 0, 0, false, false, false, false, 0, null); 
      var allowDefault = anchorObj.dispatchEvent(evt);
      // you can check allowDefault for false to see if
      // any handler called evt.preventDefault().
      // Firefox will *not* redirect to anchorObj.href
      // for you. However every other browser will.
    }
  }
}
</script>
</head>
<body>

<div onclick="alert('Container clicked')">
  <a id="link" href="#" onclick="alert((event.target || event.srcElement).innerHTML)">Normal link</a>
</div>

<button type="button" onclick="fakeClick(event, document.getElementById('link'))">
  Fake Click on Normal Link
</button>

<br /><br />

<div onclick="alert('Container clicked')">
    <div onclick="fakeClick(event, this.getElementsByTagName('a')[0])"><a id="link2" href="#" onclick="alert('foo')">Embedded Link</a></div>
</div>

<button type="button" onclick="fakeClick(event, document.getElementById('link2'))">Fake Click on Embedded Link</button>

</body>
</html>

Demo hier.

Es vermeidet die Rekursion in Nicht-IE-Browsern, indem das Ereignisobjekt geprüft wird, das den simulierten Klick initiiert, und das Attribut target des Ereignisses (das während der Weitergabe unverändert bleibt) geprüft.

Offensichtlich hält IE dies intern einen Verweis auf sein globales event-Objekt . DOM-Ebene 2 definiert keine solche globale Variable, daher muss der Simulator seine lokale Kopie von event übergeben.

62
Crescent Fresh

nun, Sie können den Klickversand sehr schnell über jQuery testen

$('#link-id').click();

Wenn Sie immer noch Probleme mit dem Klick auf das Ziel haben, können Sie dies immer tun

$('#link-id').click( function( event, anchor )
{
  window.open( anchor.href, anchor.target, '' );
  event.preventDefault();
  return false;
});
11
Peter Bailey

Zitiert aus https://developer.mozilla.org/de/DOM/element.click

Die Click-Methode ist für INPUT-Elemente des Typs button, checkbox, radio, reset oder submit vorgesehen. Gecko implementiert die Click-Methode nicht für andere Elemente, von denen erwartet wird, dass sie auf Mausklicks reagieren, wie z. B. Links (A-Elemente), und löst auch nicht unbedingt das Klickereignis anderer Elemente aus.

Nicht-Gecko-DOMs können sich anders verhalten. 

Leider klingt es so, als hätten Sie bereits die beste Lösung für Ihr Problem gefunden.

Als Randbemerkung stimme ich zu, dass Ihre Lösung nicht ideal erscheint, aber wenn Sie die Funktionalität in einer Methode verkapseln (ähnlich wie bei JQuery), ist das nicht so schlimm.

11
Chris Shouts

Es gibt einen einfacheren Weg, dies zu erreichen.

HTML 

<a href="https://getbootstrap.com/" id="fooLinkID" target="_blank">Bootstrap is life !</a>

JavaScript 

// Simulating click after 3 seconds
setTimeout(function(){
  document.getElementById('fooLinkID').click();
}, 3 * 1000);

Verwenden von normalem Javascript zum Simulieren eines Klicks zusammen mit der Adressierung der Zieleigenschaft.

Das Funktionsbeispiel finden Sie hier auf jsFiddle .

6
Gaurav Gandhi

Keine der oben genannten Lösungen spricht die generische Absicht der ursprünglichen Anfrage an. Was ist, wenn wir die ID des Ankers nicht kennen? Was ist, wenn es keine ID hat? Was ist, wenn es nicht einmal einen href-Parameter hat (z. B. das vorige/nächste Symbol eines Karussells)? Was ist, wenn wir die Aktion agnostisch auf mehrere Anker mit unterschiedlichen Modellen anwenden möchten? Hier ist ein Beispiel, das etwas tut, anstatt einen Klick auszuführen, und simuliert später den Klick (für einen Anker oder ein anderes Tag):

var clicker = null;
$('a').click(function(e){ 
    clicker=$(this); // capture the clicked dom object
    /* ... do something ... */
    e.preventDefault(); // prevent original click action
});
clicker[0].click(); // this repeats the original click. [0] is necessary.
0
Vision Hive