web-dev-qa-db-fra.com

Puis-je appeler jquery click () pour suivre un lien <a> si je n'y ai pas lié un gestionnaire d'événements avec bind ou un clic déjà?

J'ai une minuterie dans mon JavaScript qui doit émuler en cliquant sur un lien pour aller à une autre page une fois le temps écoulé. Pour ce faire, j'utilise la fonction click() de jQuery. J'ai aussi 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.

J'utilise Firefox pour tout ce que je décris dans cette question, mais je m'intéresse également à ce que les autres navigateurs vont faire avec cela.

Si je n'ai pas utilisé $('a').bind('click',fn) ou $('a').click(fn) pour définir un gestionnaire d'événements, l'appel de $('a').click() ne semble alors absolument rien faire. 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 configure d'abord un gestionnaire d'événements, il fonctionnera 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 moi-même.

Ma question est donc double: est-ce un comportement étrange parce que je fais quelque chose de mal quelque part? et pourquoi appeler click() ne fait-il rien avec le comportement par défaut si je n'ai pas créé mon propre gestionnaire?

EDIT:

Comme Hoffman l'a déterminé lorsqu'il a tenté de reproduire mes résultats, les résultats que j'ai décrits ci-dessus ne se sont pas produits. Je ne sais pas ce qui a causé les événements que j'ai observés hier, mais aujourd'hui, je suis certain que ce n'est pas ce que j'ai décrit dans la question.

La réponse est donc que vous ne pouvez pas "simuler" des clics dans le navigateur et que jQuery n’appelle que votre gestionnaire d’événements. Vous pouvez toujours utiliser window.location pour changer de page, et cela me convient parfaitement.

174
Mnebuerquo

Intéressant, c'est probablement une "demande de fonctionnalité" (c'est-à-dire un bogue) pour jQuery. L'événement de clic jQuery déclenche uniquement l'action de clic (appelé événement onClick sur le DOM) sur l'élément si vous liez un événement jQuery à l'élément. Vous devriez vous rendre sur les listes de diffusion jQuery ( http://forum.jquery.com/ ) et en rendre compte. Cela pourrait être le comportement souhaité, mais je ne le pense pas.

MODIFIER:

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

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

Il ne va jamais sur google.com sauf si vous cliquez directement sur le lien (avec ou sans le code commenté). Notez également que même si vous liez l'événement click au lien, il ne passe toujours pas au violet une fois que vous avez cliqué sur le bouton. Il ne passe au violet que si vous cliquez directement sur le lien.

J'ai fait des recherches et il semble que le .click ne soit pas supposé fonctionner avec les balises 'a' car le navigateur ne suporte pas le "faux clic" avec javascript. Je veux dire, 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 la couleur du lien visité, la valeur par défaut est le violet dans la plupart des navigateurs). Il n’a donc aucun sens de faire en sorte que l’événement $ (). Click fonctionne avec les balises 'a' car le fait de passer à l’attribut href ne fait pas partie de l’événement onClick, mais est codé en dur dans le navigateur.

88
Hoffmann

Une autre option consiste bien sûr à utiliser le code JavaScript de Vanilla:

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

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

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

EDIT: Voici pourquoi il ne clique pas, à partir de la fonction trigger, source jQuery pour la version 1.3.2:

 // 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) {}
    }

Après avoir appelé les gestionnaires (s’il en existe), jQuery déclenche un événement sur l’objet. Cependant, il n'appelle les gestionnaires natifs pour les événements de clic que si l'élément n'est pas un lien. Je suppose que cela a été fait à dessein pour une raison quelconque. Cela devrait être vrai, qu'un gestionnaire d'événement soit défini ou non. Je ne sais donc pas pourquoi, dans votre cas, attacher un gestionnaire d'événement a provoqué l'appel du gestionnaire natif onClick. Vous devrez faire ce que j'ai fait et suivre l'exécution pour voir où elle est appelée.

63
Ryan Lynch

Les gestionnaires de clic sur les balises d'ancrage constituent un cas particulier dans jQuery.

Je pense que vous êtes peut-être en train de confondre l'événement onclick de l'ancre (connu du navigateur) avec l'événement click de l'objet jQuery qui englobe la notion de balise d'ancrage du DOM.

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

Les sections pertinentes de la source sont les lignes 2643-2645 (je l’ai scindée en plusieurs lignes pour faciliter la compréhension):

// 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;
5
marshally

Déclenchez un élément Hyperlink qui se trouve à l'intérieur de l'élément que vous souhaitez connecter à jquery .click ()

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

Dans votre script, vous vous connectez au conteneur principal sur lequel vous souhaitez que l'événement click se produise. Ensuite, vous utilisez la méthodologie standard jquery pour rechercher l'élément (type, classe, id) et déclencher le clic. Qu'est-ce qui se passe, c'est que jquery entre dans une fonction récursive pour déclencher le clic et que vous interrompez la fonction récursive en prenant les fonctions d'événements 'e' et stopPropagation () et que vous retourniez la valeur false, car vous ne voulez pas que jquery fasse autre chose que de déclencher le lien.

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

La solution alternative consiste à envelopper les conteneurs dans l'élément et à les placer comme des conteneurs à l'intérieur au lieu de. Configurez les étendues pour que le bloc d'affichage soit conforme aux normes w3c.

3
Paul Styles

JS/jQuery ne prend pas en charge le comportement par défaut des liens "cliqués" par programme.

Ce que vous pouvez faire, c'est créer un formulaire et le soumettre. Ainsi, vous n'avez pas à utiliser window.location ou window.open, qui sont souvent bloqués par les navigateurs en tant que fenêtres contextuelles indésirables.

Ce script a 2 méthodes différentes: une qui tente d'ouvrir 3 nouveaux onglets/fenêtres (il n'en ouvre qu'une dans IE et Chrome, plus d'infos ci-dessous) et une qui déclenche un événement personnalisé lors d'un clic sur un lien.

Voici comment:

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

});

Ce qu'il fait est pour chaque élément de lien:

  1. Créer un formulaire
  2. Lui donner des attributs
  3. Ajoutez-le au DOM pour pouvoir le soumettre.
  4. Soumet le
  5. Supprimer la forme du DOM, en supprimant toute trace * Insérer un rire diabolique *

Vous avez maintenant un nouvel onglet/fenêtre qui charge "https://google.nl" (ou l’adresse de votre choix, il suffit de le remplacer). Malheureusement, lorsque vous essayez d'ouvrir plus d'une fenêtre de cette façon, vous obtenez une barre de messages Popup blocked lorsque vous essayez d'ouvrir la seconde (la première est toujours ouverte).


Plus d'informations sur la façon dont je suis arrivé à cette méthode se trouvent ici:

Ouverture d'une nouvelle fenêtre/d'un nouvel onglet sans utiliser window.open ou window.location.href)

3
Richard de Wit

Si vous avez besoin de cette fonctionnalité pour un cas ou très peu de casses. (vous n'avez pas besoin de cette fonctionnalité pour l'ensemble de l'application) Je préférerais laisser jQuery tel quel (pour de nombreuses raisons, notamment de pouvoir mettre à jour vers des versions plus récentes, CDN, etc.) et de disposer de la solution de contournement suivante:

// 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);
  })()
2
adardesign

Cela ne fait rien car aucun événement n'a été lié à l'événement. Si je me souviens bien, jQuery conserve sa propre liste de gestionnaires d'événements liés à NodeLists à des fins de performance et autres.

2
JasonWyatt

Pour ouvrir un hyperlien dans le même onglet, utilisez:

$(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;
});
1
DHARMENDRA SINGH

Vous pouvez utiliser jQuery pour sélectionner l'objet jQuery pour cet élément. Ensuite, récupérez l'élément DOM sous-jacent et appelez sa méthode click().

par id

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

ou utilisez jQuery pour cliquer sur un tas de liens par classe CSS

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