web-dev-qa-db-fra.com

Quelle est la différence entre les différentes méthodes de mise en code JavaScript dans un <a>?

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

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 de simplement du 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 cela).

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". Cela 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)"?.

82
Darryl Hein

J'apprécie assez article sur les meilleures pratiques Javascript de Matt Kruse . Dans ce document, il déclare que l'utilisation de la section href pour exécuter du code JavaScript est une mauvaise idée. Même si vous avez déclaré que JavaScript doit être activé pour vos utilisateurs, il n'y a aucune raison pour laquelle vous ne pouvez pas avoir une simple page HTML vers laquelle tous vos liens JavaScript peuvent pointer vers leur section href dans le cas où quelqu'un se tournerait hors JavaScript après la connexion. Je vous encourage fortement à toujours autoriser ce mécanisme de secours. Quelque chose comme ça respectera les "meilleures pratiques" et atteindra votre objectif:

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>
66
cowgod

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

10
eyelidlessness

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 commenter 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 garde 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 placer dans un fichier externe qui peut ensuite être compressé pour réduire la taille du fichier et mis en cache par les navigateurs clients.

4
nickf
<a href="#" onClick="DoSomething(); return false;">link</a>

Je vais le faire, ou:

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

Dépendant de la situation. Pour les applications plus grandes, la seconde est la meilleure car elle consolide ensuite votre code d'événement.

3
user19302

La méthode # 2 a une erreur de syntaxe dans FF3 et IE7. Je préfère les méthodes # 1 et # 3, parce que # 4 salit l'URI avec '#' bien qu'il cause moins de typage ... Évidemment, comme noté par d'autres réponses, la meilleure solution est de séparer le HTML de la gestion des événements.

1
Pier Luigi

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>

Cross-browser

<!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, cela fonctionnera car nous attachons l'événement au document.

Sources:

1
Timo Huovinen

J'ai remarqué une différence entre cela:

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

et ça:

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

est que si dans les deux cas vous avez:

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

puis pour le premier exemple, act2 s'exécutera avant act1 et dans le deuxième exemple, ce sera l'inverse.

1
JoelFan