Quelle est la différence entre les différentes méthodes pour insérer du code JavaScript dans un <a>?

87

J'ai vu les méthodes suivantes pour mettre du code JavaScript dans une <a>balise:

function DoSomething() { ... return false; }
  1. <a href="javascript:;" onClick="return DoSomething();">link</a>
  2. <a href="javascript:DoSomething();">link</a>
  3. <a href="javascript:void(0);" onClick="return DoSomething();">link</a>
  4. <a href="#" onClick="return DoSomething();">link</a>

Je comprends l'idée d'essayer de mettre une URL valide au lieu d'un simple code JavaScript, juste au cas où l'utilisateur n'aurait pas activé JavaScript. Mais pour les besoins de cette discussion, je dois supposer que JavaScript est activé (ils ne peuvent pas se connecter sans lui).

Personnellement, j'aime l'option 2 car elle vous permet de voir ce qui va être exécuté - particulièrement utile lors du débogage où des paramètres sont passés à la fonction. Je l'ai beaucoup utilisé et je n'ai pas trouvé de problèmes de navigateur.

J'ai lu que les gens recommandent 4, car cela donne à l'utilisateur un vrai lien à suivre, mais en réalité, # n'est pas "réel". Il n'ira absolument nulle part.

Y en a-t-il un qui n'est pas pris en charge ou qui est vraiment mauvais, lorsque vous savez que l'utilisateur a activé JavaScript?

Question connexe: Href pour les liens JavaScript: "#" ou "javascript: void (0)"? .

Darryl Hein
la source
Petit problème de syntaxe: le choix n ° 2 devrait être - <a href="javascript:DoSomething();"> lien </a> sans le "retour"
DRosenfeld
Veuillez remplacer la réponse acceptée par @eyelidlessness. Je pense que c'est la meilleure approche, car elle se soucie de la sémantique.
Michał Perłakowski

Réponses:

69

J'aime bien l'article de Matt Kruse sur les bonnes pratiques Javascript . Dans celui-ci, il déclare que l'utilisation de la hrefsection pour exécuter du code JavaScript est une mauvaise idée. Même si vous avez déclaré que vos utilisateurs doivent activer JavaScript, il n'y a aucune raison pour laquelle vous ne pouvez pas avoir une page HTML simple vers laquelle tous vos liens JavaScript peuvent pointer pour leur hrefsection dans le cas où quelqu'un désactiverait JavaScript après la connexion. Je vous encourage vivement à continuer d'autoriser ce mécanisme de secours. Quelque chose comme celui-ci respectera les "meilleures pratiques" et atteindra votre objectif:

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>
cowgod
la source
4
comme la valeur href sera affichée à l'utilisateur dans la barre d'état? (la barre en bas) J'envisagerais d'utiliser un lien un peu plus convivial, par exemple. "js.html? doSomething", la page peut toujours être du HTML statique. De cette façon, l'utilisateur verra clairement une différence entre les liens.
Gene
7
Vous pouvez remplacer cette valeur par l'attribut title, par exemple <a href="javascript_required.html" title="Does Something" onclick="doSomething(); return false;"> go </a>
Conspicuous Compiler
Il est recommandé de consigner les demandes sur la page javascript_required.html et de consigner la fonction à l'origine de l'erreur.
Timo Huovinen
2
Avez-vous pensé aux conséquences pour le référencement?
DanielBlazquez le
Le javascripttoolbox.com de Matt Kruse semble être hors ligne et à vendre.
showdev
10

Pourquoi feriez-vous cela alors que vous pouvez utiliser addEventListener/ attachEvent? S'il n'y a pas d' hreféquivalent, n'utilisez pas un <a>, utilisez a <button>et stylisez-le en conséquence.

paupière
la source
9
l'utilisation d'un bouton au lieu d'un lien n'est pas une option réalisable dans de nombreux cas.
nickf
2
Parce que ça a l'air moche. Vous pouvez ajouter une icône à côté du lien. Ils sont difficiles à formater de la même manière sur tous les navigateurs. Et généralement, les gens se déplacent vers des liens au lieu de boutons - regardez la plupart des débordements de pile.
Darryl Hein
2
Ça a l'air moche? Il ressemble à ce à quoi vous voulez qu'il ressemble. En fait, je pense que les boutons ont en fait plus de flexibilité de style que les liens, en ce sens qu'ils sont en ligne mais peuvent correctement prendre du remplissage entre les navigateurs. Tout ce qui peut être fait avec un lien peut être fait avec un bouton, en ce qui concerne CSS.
paupière
2
Span ne peut pas être axé sur le clavier.
bobince
3
Et le bouton est (halètement) sémantiquement correct. Span n'a pas de sens sémantiquement. Un bouton est exactement ce que l'auteur a l'intention d'utiliser, sémantiquement.
paupière
5

Vous avez oublié une autre méthode:

5: <a href="#" id="myLink">Link</a>

Avec le code JavaScript:

document.getElementById('myLink').onclick = function() {
    // Do stuff.
};

Je ne peux pas dire laquelle des options a le meilleur support ou qui est sémantiquement la meilleure, mais je dirai simplement que je préfère de beaucoup ce style car il sépare votre contenu de votre code JavaScript. Il conserve tout le code JavaScript ensemble, ce qui est beaucoup plus facile à maintenir (surtout si vous l'appliquez à de nombreux liens), et vous pouvez même le mettre dans un fichier externe qui peut ensuite être compressé pour réduire la taille du fichier et mis en cache par les navigateurs clients.

nickf
la source
7
Si vous avez 20 ou 30 liens différents avec JS, cela peut devenir assez fastidieux et aboutir à beaucoup de JS.
Darryl Hein
ce n'est pas plus fastidieux que de parcourir HTML pour changer de javascript. ... ou vous pouvez utiliser quelque chose comme jQuery qui peut facilement changer les événements sur plusieurs éléments à la fois ... $ ('# menu a'). click (function () {..})
nickf
1
@JKirchartz Je ne vois pas comment c'est prêcher s'il y a des raisons derrière la réponse. Si vous lisez la question, c'est vraiment "lequel de ces 4 est le meilleur", et je viens de souligner qu'il y a une autre option qu'il n'avait pas envisagée.
nickf
Je m'en fous, trololo, au moment de choisir entre ABC et D, on ne choisit pas E.
JKirchartz
3
@JKirchartz Oui, je ne pense pas que vous compreniez vraiment le but de Stack Overflow alors. Si quelqu'un demande "Quel est le meilleur pour créer une application Web dans: Cobol ou Fortran?" Il est acceptable de dire à cette personne qu'elle n'a pas envisagé toutes les possibilités. La question n'est clairement pas de savoir "laquelle de ces quatre choses est la meilleure".
nickf
3
<a href="#" onClick="DoSomething(); return false;">link</a>

Je vais faire ceci, ou:

<a href="#" id = "Link">link</a>
(document.getElementById("Link")).onclick = function() {
    DoSomething();
    return false;
};

Dépendant de la situation. Pour les applications plus volumineuses, la deuxième est la meilleure, car elle consolide votre code d'événement.

Anik Islam Abhi
la source
Si vous avez 20 ou 30 liens différents avec JS, cela peut devenir assez fastidieux et aboutir à beaucoup de JS.
Darryl Hein
et les bogues qui s'insinuent dans votre code peuvent être TRÈS difficiles à déboguer. Ces bugs apparaissent très facilement, comme en témoigne votre premier exemple. :)
nickf
1

La méthode n ° 2 a une erreur de syntaxe dans FF3 et IE7. Je préfère les méthodes n ° 1 et n ° 3, car n ° 4 sale l'URI avec '#' bien que cela entraîne moins de frappe ... De toute évidence, comme indiqué par d'autres réponses, la meilleure solution est de séparer le html de la gestion des événements.

Pier Luigi
la source
Méthode n ° 2 de quoi? Les questions ne restent pas dans le même ordre que lorsque VOUS les avez vues.
Diodeus - James MacFarlane
La méthode n ° 4 ne gâchera pas l'URI si vous vous en assurez return false. Pour cette raison, la méthode n ° 4 est probablement la meilleure (parmi celles énumérées).
Már Örlygsson
2
@Diodeus, je crois que Pier faisait référence à la liste numérotée dans la question , qui est en fait là depuis que la question a été publiée en premier lieu.
paupière
1

Une différence que j'ai remarquée entre ceci:

<a class="actor" href="javascript:act1()">Click me</a>

et ça:

<a class="actor" onclick="act1();">Click me</a>

est-ce que si dans les deux cas vous avez:

<script>$('.actor').click(act2);</script>

puis pour le premier exemple, act2s'exécutera avant act1et dans le second exemple, ce sera l'inverse.

JoelFan
la source
1

Navigateurs modernes uniquement

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }
    doc.addEventListener('click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault();
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

Navigateur croisé

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var cb_addEventListener = function(obj, evt, fnc) {
        // W3C model
        if (obj.addEventListener) {
            obj.addEventListener(evt, fnc, false);
            return true;
        } 
        // Microsoft model
        else if (obj.attachEvent) {
            return obj.attachEvent('on' + evt, fnc);
        }
        // Browser don't support W3C or MSFT model, go on with traditional
        else {
            evt = 'on'+evt;
            if(typeof obj[evt] === 'function'){
                // Object already has a function on traditional
                // Let's wrap it with our own function inside another function
                fnc = (function(f1,f2){
                    return function(){
                        f1.apply(this,arguments);
                        f2.apply(this,arguments);
                    }
                })(obj[evt], fnc);
            }
            obj[evt] = fnc;
            return true;
        }
        return false;
    };
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }

    cb_addEventListener(doc, 'click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault ? e.preventDefault() : e.returnValue = false;
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

Vous pouvez l'exécuter avant que le document ne soit prêt, en cliquant sur les boutons fonctionnera car nous attachons l'événement au document.

Sources:

Timo Huovinen
la source