2011-09-29 4 views
3

Je me demande simplement s'il existe un moyen avec jquery d'intercepter un lien quand on clique dessus. Le problème est que certains des liens sur ma page ne sont pas chargés lors du premier chargement de la page. Je me souviens vaguement avoir entendu que jquery avait le moyen d'intercepter tous les liens actuels et futurs. Voici le code que j'ai. Il fonctionne sur tous les liens il y avait là au début, mais les liens qui ont été chargés sur la page plus tard ne reçoivent pas intercepté par cette fonctionIntercepter tous les liens actuels et futurs

$('a').trackClick({ 
     areaClick: function(element) { return getAreaClicked(element); }, 
     href: function(element) { return getHrefFromElement(element); }, 
     text: function(element) { return getTextFromElement(element); }, 
     exceptions: function(element) { return isException(element); } 
    }); 

Répondre

5

Vous avez besoin jquery voir en direct ici: http://api.jquery.com/live/

$('a').live('click', function(e){ 

var element = $(this); 
var data = {areaClick: function(element) { return getAreaClicked(element); }, 
      href: function(element) { return getHrefFromElement(element); }, 
      text: function(element) { return getTextFromElement(element); }, 
      exceptions: function(element) { return isException(element); } 
} 
    trackClick(data); 

    }); 
+0

ce que ce code ne exactement la même chose que mon code ci-dessus. Quand je le colle, j'obtiens deux erreurs javascript dans d'autres parties du code qui n'existaient pas auparavant. Ce n'est pas du code que j'ai écrit donc je ne sais pas vraiment ce qui se passe, juste besoin de réparer le bug de lien futur! – Kaskade

+0

J'ai modifié le code ci-dessus pour correspondre - devrait fonctionner maintenant – Ash

+7

Les futurs lecteurs voyant cela comme la bonne réponse doivent savoir que .live() était déjà un choix découragé avec '.delegate()' étant préféré; mais plus important encore les deux sont maintenant remplacés par '.on()' en utilisant la syntaxe de délégation. http://api.jquery.com/on/ –

3

Utilisez le gestionnaire d'événements de live jQuery:

$('a').live('click', function() { 
    ... 
}); 
7

[edit: je reçois le upvote de temps en temps sur cette réponse, donc je voulais le mettre à jour avec plus de courant (en mai 2015) pratique]:

Par ma réponse originale, déléguer l'auditeur est une meilleure pratique. La syntaxe actuelle de «meilleure pratique» pour jQuery est .on(). Il ne diffère que dans l'ordre, et pour moi est plus intuitive sémantiquement:

$('#parent').on('click', 'a', function(event) { 
    event.preventDefault(); 
    // do the rest of your stuff 
} 

Le reste de ma première réponse est toujours valable.


Si vous ne voulez pas le comportement de clic par défaut, vous devez également arrêter le bouillonnement d'événement. Je préfère déléguer en direct, alors voici ma suggestion:

$('#parent').delegate('a', 'click', function(event) { 
    event.preventDefault(); 
    // do the rest of your stuff 
}); 

Le "#parent" est juste un échantillon. Vous utiliseriez n'importe quel sélecteur approprié qui sera un ancêtre permanent de vos balises d'ancrage. Pourrait même monter aussi haut que "corps", mais souvent un ID de wrapper de quelque description fonctionne aussi bien.

[edit: J'ai récemment vu une critique, ce qui signifie que cette réponse est vue par quelqu'un là-bas. Il convient de noter que .live() est maintenant dépréciée, et bien que .delegate() est prise en charge, la syntaxe proposée officiellement est .on() utilisé comme délégant:

$('#parent').on('click', 'a', function(event) { 
    event.preventDefault(); 
    // do the rest of your stuff 
}); 
+0

vous pouvez faire exactement la même chose avec live(), ce qui est syntaxiquement plus correct, car vous n'avez pas besoin d'utiliser le parent – Ash

+0

@Ash Oui, vous pouvez faire la même chose chose avec 'live()', cependant, 'live()' est inefficace en ce sens qu'il va d'abord sélectionner toutes les balises d'ancrage, puis ne rien faire avec elles. C'est moins un problème si c'est en dehors de $ (document) .ready() et dans l'en-tête de la page. –

+1

Je ne suis pas sûr de ce que vous entendez par "syntaxiquement plus correct." Les deux fonctions décrivent ce qu'elles font. Les avantages de .delegate sont bien documentés, et même dans le cas où les avantages de performances réels sont moins dramatiques (par Kevin B), ce n'est pas une mauvaise habitude de passer à .delegate() comme une fonction de liaison par clic. En outre, j'ai dit "je préfère" et fourni une alternative. Les options ne peuvent pas être une mauvaise chose! –

2

L'option la plus simple est d'utiliser la méthode live() de jQuery, bien que ce soit assez cher. Si possible, delegate() est une meilleure option, et il y a des postes couple ici qui décrivent la différence entre les deux:

Jquery live() vs delegate()
jQuery: live() vs delegate()

En général, la meilleure option est de lier simplement tout ce que vous devez au nouveaux éléments <a> chargés via AJAX. Par exemple:

$.ajax({ 
    url: 'http://example.com' 
    type: 'GET' 
    data: 'whatever' 
    success: function(data){ 
     //after inserting the response somewhere... 
     $('.insertedContent').find('a'.trackClick({ 
     areaClick: function(element) { return getAreaClicked(element); }, 
     href: function(element) { return getHrefFromElement(element); }, 
     text: function(element) { return getTextFromElement(element); }, 
     exceptions: function(element) { return isException(element); } 
     }); 
    } 
} 
0

Comme il a été dit, les réponses et .delegate().live() recommandent sont out of date. J'ai eu un problème similaire: j'avais déjà plusieurs gestionnaires de clics en jeu sur différents éléments, mais je voulais ajouter un gestionnaire de clics supplémentaire pour tout attraper et éventuellement agir avant les autres.Mon cas d'utilisation pour cela voulait que divers outils dans une application Web «réinitialiser» à l'état par défaut lorsque d'autres outils ont été cliqués.

Voici ma solution ...

$(document).on("click", function(e){ 
    // This catches all clicks. 
    // It can be suppressed if the target uses e.stopPropagation() 
}); 

// To start the bubbling from an element "higher" than the document, 
// then use delegation, e.g.: 
// $(document).on("click", ".your_class", function(e){ etc }) 
// This can be really useful if you only have one sensitive area in the layout, 
// or you want different "master" click behaviours for different areas! 

$("#my_element").on("click", function(e){ 
    // prevent the default action, e.g. prevent "#" navigation on <a href="#"> 
    e.preventDefault(); 
    // prevent the click bubbling to the $(document) handler 
    e.stopPropagation(); 
    // now do my stuff 
    // ... 
}); 

$("#my_other_element").on("click", function(e){ 
    // prevent the default action, e.g. prevent "#" navigation on <a href="#"> 
    e.preventDefault(); 
    // this time I want the "catch all" to fire 
    // so I don't do stopPropagation() 
    // now do my stuff 
    // ... 
}); 
Questions connexes