176 votes

Est-ce que je peux utiliser la fonction click() de jQuery pour suivre un lien <a> si je n'ai pas déjà associé de gestionnaire d'événement avec bind ou click ?

Je dispose d'un minuteur dans mon JavaScript qui doit émuler le clic sur un lien pour accéder à une autre page une fois le temps écoulé. Pour cela, j'utilise la fonction click() de jQuery. J'ai également utilisé $().trigger() et window.location, et je peux le faire fonctionner comme prévu avec les trois.

J'ai observé un comportement étrange avec click() et j'essaie de comprendre ce qui se passe et pourquoi.

Je n'utilise Firefox pour tout ce que je décris dans cette question, mais je suis également intéressé par ce que les autres navigateurs feront avec ça.

Si je n'ai pas utilisé $('a').bind('click',fn) ou $('a').click(fn) pour définir un gestionnaire d'événements, alors appeler $('a').click() semble ne rien faire du tout. Il n'appelle pas le gestionnaire par défaut du navigateur pour cet événement, car le navigateur ne charge pas la nouvelle page.

Cependant, si je définis d'abord un gestionnaire d'événements, alors ça fonctionne comme prévu, même si le gestionnaire d'événements ne fait rien.

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

Cela charge la nouvelle page comme si j'avais cliqué sur le lien moi-même.

Ma question est donc double: Ce comportement étrange est-il dû à une erreur de ma part quelque part ? et pourquoi click() ne fait rien avec le comportement par défaut si je n'ai pas créé de gestionnaire personnel ?


Comme Hoffman l'a déterminé lorsqu'il a essayé de reproduire mes résultats, le résultat que j'ai décrit ci-dessus ne se produit pas réellement. Je ne suis pas sûr de ce qui a provoqué les événements que j'ai observés hier, mais je suis certain aujourd'hui que ce n'était pas ce que j'ai décrit dans la question.

Donc, la réponse est que vous ne pouvez pas "simuler" des clics dans le navigateur et que tout ce que fait jQuery est d'appeler votre gestionnaire d'événements. Vous pouvez toujours utiliser window.location pour changer de page, et cela fonctionne bien pour moi.

2 votes

Peut-être une solution: stackoverflow.com/questions/31687759/…

244voto

Peter Points 14647

Une autre option est bien sûr d'utiliser simplement JavaScript vanilla :

document.getElementById("a_link").click()

1 votes

Cela ne fonctionne pas dans Safari, et selon la spécification HTML seuls les inputs doivent mettre en œuvre cela.

4 votes

Dang! Ce code fonctionne! Mais je dois dire que ce n'est pas tout à fait du javascript "vanilla" car il utilise un élément de jquery, donc c'est un javascript jquery un peu spécial.... Ça marche sur Firefox 24 et IE 10.

0 votes

@BGM, d'accord, mais le click() n'est pas sur un élément jquery. Vous pourriez le remplacer par getElementById("..").click()

90voto

Hoffmann Points 3585

Intéressant, il s'agit probablement d'une "demande de fonctionnalité" (c'est-à-dire un bogue) pour jQuery. L'événement de clic de jQuery ne déclenche le clic que sur l'élément si vous liez un événement jQuery à l'élément. Vous devriez aller sur les listes de diffusion de jQuery ( http://forum.jquery.com/ ) et signaler cela. Cela pourrait être le comportement souhaité, mais je ne le pense pas.

ÉDITER :

J'ai effectué quelques tests et ce que vous avez dit est incorrect, même si vous liez une fonction à une balise 'a', cela ne vous emmène toujours pas sur le site Web spécifié par l'attribut href. Essayez le code suivant :

  $(document).ready(function() {
   /* Essayez de décommenter ceci :
   $('#a').click(function () {
    alert('jQuery.click()');
    return true;
   });
   */
  });
  function button_onClick() {
   $('#a').click();
  }
  function a_onClick() {
   alert('a_onClick');
  }

  aaa 

Il ne va jamais sur google.com à moins que vous ne cliquiez directement sur le lien (avec ou sans le code commenté). Remarquez également que même si vous liez l'événement de clic au lien, il ne devient pas violet une fois que vous cliquez sur le bouton. Il ne devient violet que si vous cliquez directement sur le lien.

J'ai fait des recherches et il semble que la fonction .click ne soit pas censée fonctionner avec les balises 'a' car le navigateur ne prend pas en charge le "clic simulé" avec JavaScript. Autrement dit, vous ne pouvez pas "cliquer" sur un élément avec JavaScript. Avec les balises 'a', vous pouvez déclencher son événement onClick mais le lien ne changera pas de couleur (pour le couleur de lien visité, le violet par défaut dans la plupart des navigateurs). Il ne serait donc pas logique de faire fonctionner l'événement $().click avec les balises 'a' puisque l'action de se rendre à l'attribut href ne fait pas partie de l'événement onClick, mais est codée en dur dans le navigateur.

7 votes

J'ai essayé votre code, et il fait exactement ce que vous avez dit qu'il fait, mais mon code fait comme je l'ai décrit ci-dessus. Je vais faire quelques expériences supplémentaires et voir si je peux mettre en place un exemple simple de mes résultats que vous pouvez essayer.

1 votes

D'accord. Ça doit avoir été quelque chose que j'ai mal fait. J'étais absolument certain au moment où j'ai posté ma question que ça marchait, mais depuis que j'ai essayé votre exemple, le mien ne marche plus. Je vais simplement revenir à utiliser window.location pour changer la page et ne pas essayer de simuler le clic.

0 votes

En effet, la méthode click() n'est pas destinée à générer de faux clics, mais parfois nous pouvons l'utiliser pour cliquer sur des boutons ou des formulaires avec des injections de javascript ou simplement pour la commodité lors de la création d'un raccourci temporaire par-dessus des fonctions javascript existantes.

65voto

Ryan Lynch Points 5531

Si vous regardez le code de la fonction $.click, je parie qu'il y a une instruction conditionnelle qui vérifie si l'élément a des écouteurs enregistrés pour l'événement click avant de continuer. Pourquoi ne pas simplement obtenir l'attribut href du lien et changer manuellement l'emplacement de la page?

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

Voici pourquoi cela ne fonctionne pas comme un clic. Depuis la fonction trigger, la source jQuery pour la version 1.3.2 :

 // Gérer le déclenchement des gestionnaires natifs .onfoo (et sur les liens car nous n'appelons pas .click() pour les liens)
 if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
     event.result = false;

 // Déclencher les événements natifs (sauf pour les clics sur les liens)
 if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
     this.triggered = true;
     try {
         elem[ type ]();
         // Empêcher Internet Explorer de générer une erreur pour certains éléments masqués
     }
     catch (e) 
     {
     }
 }

Après avoir appelé les gestionnaires (s'il y en a), jQuery déclenche un événement sur l'objet. Cependant, il n'appelle les gestionnaires natifs que pour les événements de clic si l'élément n'est pas un lien. Je suppose que cela a été fait délibérément pour une raison quelconque. Cependant, cela devrait être vrai que l'objet ait un gestionnaire d'événements défini ou non, donc je ne suis pas sûr pourquoi dans votre cas attacher un gestionnaire d'événements a provoqué l'appel du gestionnaire onClick natif. Vous devrez faire comme moi et suivre l'exécution pour voir où cela est appelé.

0 votes

Je peux certainement utiliser window.location et href comme je l'ai mentionné dans la question. J'essaie de comprendre ce qui se passe dans le click() de jquery et ce qui cause les résultats que j'ai observés.

0 votes

J'ai modifié ma réponse pour montrer où dans le code source de jQuery il traite des appels $.click() sur les liens.

2 votes

Window.location fonctionne, mais ne poste pas le référent HTTP, et casse le bouton retour.

5voto

marshally Points 2260

Les gestionnaires de clic sur les balises d'ancre sont un cas spécial en jQuery.

Je pense que vous pourriez être confus entre l'événement onclick de l'ancre (connu par le navigateur) et l'événement de clic de l'objet jQuery qui encapsule la notion de balise d'ancre du DOM.

Vous pouvez télécharger la source de jQuery 1.3.2 ici.

Les sections pertinentes de la source sont les lignes 2643-2645 (j'ai divisé cela en plusieurs lignes pour faciliter la compréhension):

// Gérer le déclenchement des gestionnaires .onfoo natifs (et sur les liens puisque nous ne appelons pas .click() pour les liens)
if (
     (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && 
       elem["on"+type] && 
       elem["on"+type].apply( elem, data ) === false
   )
     event.result = false;

3voto

Paul Styles Points 31

Déclenchez un élément hyperlien qui est à l'intérieur de l'élément auquel vous souhaitez connecter le .click() de jQuery :

Dans votre script, vous attachez l'événement de clic au conteneur principal sur lequel vous souhaitez que l'événement de clic se produise. Ensuite, vous utilisez la méthodologie standard de jQuery pour trouver l'élément (type, classe et id) et déclencher le clic. jQuery entre dans une fonction récursive pour déclencher le clic et vous interrompez la fonction récursive en prenant l'événement 'e' et la fonction stopPropagation() et en renvoyant false, car vous ne voulez pas que jQuery fasse quoi que ce soit d'autre que de déclencher le lien.

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

Une solution alternative consiste à envelopper les conteneurs dans l'élément et à placer des en tant que conteneurs à l'intérieur au lieu de

. Définissez les spans pour afficher en bloc afin de respecter les normes du W3C.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X