Comment puis-je simuler un clic à une balise d'ancrage?

je veux simuler un clic sur une étiquette d'ancrage avec tous les extras comme la manipulation correcte de cible.

il semble y avoir une méthode" [click ()] [3] " pour l'objet DOM d'anchor mais tous les navigateurs ne supportent pas cette méthode. Firefox lance cette erreur:

erreur: anchorObj.click n'est pas une fonction

il fonctionne aussi étrangement sur Opera 10 et Konqueror, provoquant des clics infinis pour se produire quand il est appelé à l'intérieur onclick gestionnaire d'un div entourant. Je suppose que seul le IE8 fonctionne. Quoi qu'il en soit, je ne veux pas car les principaux navigateurs ont généralement des problèmes avec elle.

j'ai trouvé cette solution alternative pour Firefox dans les forums Mozilla:

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); 

cela me semble trop laid et encombrant pour moi. Je ne sais pas si c'est compatible et je veux éviter d'écrire du code spécifique au navigateur autant que possible.

Je ne peux pas utiliser l'emplacement.href = anchorObj.href; parce qu'il ne gère pas l'attribut "target". Je peux faire un codage dur basé sur la valeur de la cible, mais j'aimerais éviter ça aussi.

il est suggéré de passer à JQuery mais je ne suis pas sûr de la façon dont il gère la propriété cible soit depuis que je n'ai pas travaillé avec elle avant.

44
demandé sur Sedat Kapanoglu 2009-09-14 17:36:48

5 réponses

voici un cas d'essai complet qui simule l'événement click , appelle tous les manipulateurs attachés (peu importe comment ils ont été attachés), maintient l'attribut "target" ( "srcElement" dans IE), bulles comme un événement normal, et émule la prévention de la récursion de IE. Testé en FF 2, Chrome 2.0, Opera 9.10 et bien sûr 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>

démo ici.

il évite la récursion dans les navigateurs non-IE par inspecter l'objet événement qui déclenche le clic simulé, en inspectant l'attribut target de l'événement (qui reste inchangé pendant la propagation ).

de toute évidence, IE fait cela à l'interne contenant une référence à son global event object . Le niveau DOM 2 ne définit pas une telle variable globale, c'est pourquoi le simulateur doit passer dans sa copie locale de event .

62
répondu Crescent Fresh 2009-12-03 17:18:23

Eh bien, vous pouvez très rapidement tester le click dispatch via jQuery comme ainsi

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

si vous avez toujours des problèmes avec click concernant la cible, vous pouvez toujours faire ceci""

$('#link-id').click( function( event, anchor )
{
  window.open( anchor.href, anchor.target, '' );
  event.preventDefault();
  return false;
});
11
répondu Peter Bailey 2009-09-14 14:04:22

Cité de https://developer.mozilla.org/en/DOM/element.click

la méthode click est destinée à être utilisée avec des éléments D'entrée de type bouton, case à cocher, radio, réinitialiser ou soumettre. Gecko n'implémente pas la méthode click sur d'autres éléments susceptibles de répondre à des clics de souris tels que les liens (A elements), pas plus qu'elle ne déclenche nécessairement l'événement click d'autres éléments.

Non Gecko Les Dom peuvent se comporter différemment.

malheureusement, il semble que vous avez déjà découvert la meilleure solution à votre problème.

comme note d'accompagnement, je suis d'accord que votre solution semble moins qu'idéale, mais si vous encapsulez la fonctionnalité à l'intérieur d'une méthode (un peu comme JQuery le ferait) ce n'est pas si mal.

11
répondu Chris Shouts 2009-09-14 14:05:38

il y a un moyen plus simple de le réaliser,

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);

utilisant javascript simple pour simuler un clic avec l'adresse de la propriété cible.

vous pouvez consulter l'exemple de travail ici sur jsFiddle .

5
répondu Gaurav Gandhi 2017-04-11 16:20:22

aucune des solutions ci-dessus ne répond à l'intention générale de la requête initiale. Et si on ne connaît pas l'identité de l'ancre? Que faire si il n'a pas un id? Et s'il n'a même pas de paramètre href (par exemple Prev/next icône dans un carrousel)? Que faire si nous voulons appliquer l'action à plusieurs ancrages avec différents modèles d'une manière agnostique? Voici un exemple qui fait quelque chose au lieu d'un clic, puis simule plus tard le clic (pour n'importe quelle ancre ou autre étiquette):

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
répondu Vision Hive 2018-06-12 06:11:54