155 votes

Pourquoi utiliser onClick () en HTML est-il une mauvaise pratique?

J'ai souvent entendu dire que l'utilisation d'événements JavaScript, tels que onClick() , en HTML est une mauvaise pratique, car elle n'est pas bonne pour la sémantique. Je voudrais savoir quels sont les inconvénients et comment corriger le code suivant?

 <a href="#" onclick="popup('/map/', 300, 300, 'map'); return false;">link</a>
 

180voto

Michael Borgwardt Points 181658

Vous êtes probablement parler de Javascript discret, qui devrait ressembler à ceci:

<a href="#" id="someLink">link</a>

avec la logique dans un centre de fichier javascript à la recherche de quelque chose comme ceci:

$('#someLink').click(function(){
    popup('/map/', 300, 300, 'map'); 
    return false;
});

Les avantages sont

  • comportement (Javascript) est séparé de présentation (HTML)
  • pas de mélange de langues
  • vous êtes à l'aide d'un framework javascript comme jQuery qui peut traiter la plupart des problèmes de navigateur pour vous
  • Vous pouvez ajouter un comportement à un grand nombre d'éléments HTML à la fois, sans duplication de code

43voto

Rich Bradshaw Points 33598

Si vous utilisez jQuery, puis:

HTML:

 <a id="#openMap" href="http://stackoverflow.com/map/">link</a>

JS:

$(document).ready(function() {
    $("#openMap").click(function(){
        popup('/map/', 300, 300, 'map');
        return false;
    });
});

Cela a l'avantage de travailler sans JS, ou si l'utilisateur moyen clique sur le lien.

Cela signifie aussi que je ne pouvais gérer générique popups par la réécriture de nouveau:

HTML:

 <a class="popup" href="http://stackoverflow.com/map/">link</a>

JS:

$(document).ready(function() {
    $(".popup").click(function(){
        popup($(this).attr("href"), 300, 300, 'map');
        return false;
    });
});

Ce serait vous permettent d'ajouter un popup à un lien, juste en lui donnant le popup de classe.

Cette idée pourrait être de s'étendre de la sorte:

HTML:

 <a class="popup" data-width="300" data-height="300" href="http://stackoverflow.com/map/">link</a>

JS:

$(document).ready(function() {
    $(".popup").click(function(){
        popup($(this).attr("href"), $(this).data('width'), $(this).data('height'), 'map');
        return false;
    });
});

Je peux maintenant utiliser le même code pour beaucoup de fenêtres pop-up sur mon site en entier sans avoir à écrire des charges de onclick trucs! Yay pour la réutilisabilité!

Cela signifie également que si plus tard je décide que les popups sont mauvaises pratiques, (ce qu'ils sont!) et que je veux remplacer par un style lightbox fenêtre modale, je peux changer:

popup($(this).attr("href"), $(this).data('width'), $(this).data('height'), 'map');

pour

myAmazingModalWindow($(this).attr("href"), $(this).data('width'), $(this).data('height'), 'map');

et tous mes popups sur l'ensemble de mon site sont maintenant à travailler de façon totalement différente. Je pourrais même faire de la fonctionnalité détection de décider quoi faire un pop-up, ou de stocker les utilisateurs de préférence pour les autoriser ou non. Avec la ligne onclick, cela nécessite un énorme copier et coller de l'effort.

24voto

Greg Bulmash Points 301

Avec de très grandes applications JavaScript, des programmeurs utilisent de plus encapsulation de code pour éviter de polluer la portée globale. Et pour faire une fonction disponible pour l'action onClick dans un élément HTML, il doit être dans la portée globale.

Vous avez peut-être vu JS fichiers qui ressemblent à ça...

(function(){
    ...[some code]
}());

Ces sont Immédiatement appelé les Expressions de Fonction (IIFEs) et toute fonction déclarée à l'intérieur d'eux n'existent que dans leur portée interne.

Si vous déclarez function doSomething(){} dans une IIFE, puis de faire l' doSomething() d'un élément de l'action onClick dans votre page HTML, vous obtiendrez une erreur.

Si, d'autre part, vous créez un eventListener de l'élément à l'intérieur de cette IIFE et appelez - doSomething() lorsque l'auditeur détecte un événement de clic, vous êtes bon, car l'auditeur et l' doSomething() part de la IIFE.

Pour peu d'applications web en un minimum de code, il n'a pas d'importance. Mais si vous aspirez à écrire un grand, facile à maintenir les bases de codes, onclick="" est une habitude que vous devriez éviter.

21voto

Alnitak Points 143355

Il n'est pas bon pour plusieurs raisons:

  • il mélange le code et le balisage
  • le code écrit ce chemin traverse eval
  • et s'exécute dans le contexte global

La chose la plus simple serait d'ajouter un name attribut à votre <a> élément, alors vous pourriez faire:

document.myelement.onclick = function() {
    window.popup('/map/', 300, 300, 'map');
    return false;
};

bien que la meilleure pratique serait d'utiliser un id au lieu d'un nom, et d'utiliser addEventListener() au lieu d'utiliser onclick depuis qui vous permet de lier plusieurs fonctions à un seul événement.

12voto

Graham Points 5475

Il ya quelques raisons:

  1. Je trouve le sida maintenance de séparer le balisage, c'est à dire le code HTML et des scripts côté client. Par exemple, jQuery, il est facile d'ajouter des gestionnaires d'événements par programmation.

  2. L'exemple que vous donnez sera rompue à tout agent utilisateur qui ne prend pas en charge javascript, ou a javascript désactivé. Le concept de l'amélioration progressive, encouragerait un simple lien hypertexte /map/ pour les agents utilisateurs sans javascript, puis l'ajout d'un gestionnaire de clic prgramatically pour les agents utilisateurs qui prennent en charge javascript.

Par exemple:

Balisage:

<a id="example" href="http://stackoverflow.com/map/">link</a>

Javascript:

$(document).ready(function(){

    $("#example").click(function(){
        popup('/map/', 300, 300, 'map');
        return false;
    });

})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X