2009-11-19 2 views
16

Je ne sais pas si ce que j'essaye d'accomplir est possible du tout. Je voudrais remplacer le comportement par défaut pour tous les objets d'ancrage (balise A) pour une page HTML donnée. Je sais que je peux parcourir tous les éléments A et ajouter dynamiquement un appel onclick à chacun d'entre eux à partir de la méthode onload de l'élément de corps, mais je cherche une solution plus absolue. Ce que j'ai besoin est que tous les A éléments sont-ils assignés une action onclick qui appelle une méthode qui passe l'élément href propriété comme argument, donc ce qui suit:Remplacer le comportement par défaut des objets link ('a') en Javascript

<a href="http://domain.tld/page.html"> 

devient Dynamiquement:

<a href="http://domain.tld/page.html" onclick="someMethodName('http://domain.tld/page.html'); return false;"> 

Comme je l'ai dit, la façon idéale de le faire serait de remplacer en quelque sorte la classe Ancre lorsque le document se charge. Si ce n'est pas possible, je vais utiliser la méthode des éléments en boucle A (que je sais déjà comment faire).

+0

Eh bien, avec la délégation d'événements, ils n'ont pas tous besoin d'avoir l'événement collé sur eux. Voir "Live" dans jQuery, par exemple. Ou lisez sur la délégation d'événements JavaScript. – Nosredna

+0

Typiquement, cela devrait être fait pour le HTML avant qu'il ne se rende au client. Si votre page est complexe, vous pourriez rencontrer beaucoup de programmes avec la délégation d'événements. – Ben

+0

En fait, pour l'événement "click" je m'attendrais à moins de problèmes avec la délégation.C'est comme suivre la souris qui va te tuer. – Nosredna

Répondre

30

Si vous ne voulez pas itérer sur tous vos éléments d'ancrage, vous pouvez simplement utiliser event delegation, par exemple:

document.onclick = function (e) { 
    e = e || window.event; 
    var element = e.target || e.srcElement; 

    if (element.tagName == 'A') { 
    someFunction(element.href); 
    return false; // prevent default action and stop event propagation 
    } 
}; 

Vérifiez l'exemple ci-dessus here.

+0

What'd vous dites est l'avantage de ne pas itérer sur les éléments d'ancrage? D'une certaine manière, c'est la méthode la plus importune, car cela signifie rediriger * tous * les clics dans le document! –

+4

La question mentionne explicitement ne pas itérer sur les éléments d'ancrage. – Ben

+0

Et c'est aussi plus efficace quand vous n'avez pas à passer d'abord par les éléments. – jtbandes

2
window.onload = function() { 
    var anchorElements = document.getElementsByTagName('a'); 
    for (var i in anchorElements) 
     anchorElements[i].onclick = function() { 
      alert(this.href); 
      return false; 
     } 
} 

Ceci est la manière la plus simple de le faire. Envelopper dans <script type="text/javascript">...</script> dans la tête de document et il s'exécutera au chargement de la page.

0

Il est impossible de remplacer tous les éléments d'ancrage en cas d'événement ponctuel. Vous pouvez ajouter un onclick au corps du document et avoir une logique pour voir si le même est propagé à partir d'un élément d'ancrage, et effectuer l'événement dans ce cas, mais cette solution pourrait causer des problèmes si votre page est complexe et ne propage pas les clics dans certains cas.

Je voudrais coller avec la solution getElementsByTagName si c'est faisable.

7

En utilisant jQuery:

$(function() { 
    $("a").click(function() { 
     return someMethodName($(this).attr('href')); 
    }); 
}); 

function someMethodName(href) 
{ 
    console.log(href); 
    return false; 
} 
0

Ne pas utiliser un cas s'il y a des événements multiples dont vous avez besoin pour gérer. Utilisez plutôt la composition de chaîne pour construire le chemin vers la fonction qui doit être appelée. Cela nécessite l'ajout d'un prototype à vos éléments "A" qui définissent la valeur par défaut et la chaîne à composer. Un attribut de données sur l'élément devrait pouvoir remplacer la valeur par défaut. Essentiellement, nous voulons simplement qu'un message et une action passent par défaut et soient modifiés de manière déclarative dans le balisage. L'action spécifiée doit être publiée quelque part en tant qu'API ou autre fonction de bibliothèque accessible et être appelée par lib ['funName']. Donnez-lui simplement un attribut, pas de souci de nom ou d'identifiant. Le prototype et l'attribut seront utiles pour les rebonds, parce que vous devrez rebondir.

0

Semblable à la réponse de Benji XVI, mais en utilisant querySelectorAll, par exemple dans un container div avec la classe 'container' Et en utilisant es6.

const $elems = document.querySelectorAll('.container a') 
var elems = Array.from($elems) 
elems.map(a => { 
    a.onclick = (e) => { 
    e.preventDefault() 
    window.alert('Clicking external links is disabled') 
    } 
}) 
Questions connexes