Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is using onClick() in HTML a bad practice?

People also ask

Why do we use onclick in HTML?

The onclick event executes a certain functionality when a button is clicked. This could be when a user submits a form, when you change certain content on the web page, and other things like that. You place the JavaScript function you want to execute inside the opening tag of the button.

Is Onclick obsolete?

'KeyboardEvent. keyIdentifier' is deprecated and will be removed in M53, around September 2016. See https://www.chromestatus.com/features/5316065118650368 for more details.

Is Onclick secure?

There is no protection. From the developer console/inspect element, you can modify the code in the tag.


You're probably talking about unobtrusive Javascript, which would look like this:

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

with the logic in a central javascript file looking something like this:

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

The advantages are

  • behaviour (Javascript) is separated from presentation (HTML)
  • no mixing of languages
  • you're using a javascript framework like jQuery that can handle most cross-browser issues for you
  • You can add behaviour to a lot of HTML elements at once without code duplication

If you are using jQuery then:

HTML:

 <a id="openMap" href="/map/">link</a>

JS:

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

This has the benefit of still working without JS, or if the user middle clicks the link.

It also means that I could handle generic popups by rewriting again to:

HTML:

 <a class="popup" href="/map/">link</a>

JS:

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

This would let you add a popup to any link by just giving it the popup class.

This idea could be extended even further like so:

HTML:

 <a class="popup" data-width="300" data-height="300" href="/map/">link</a>

JS:

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

I can now use the same bit of code for lots of popups on my whole site without having to write loads of onclick stuff! Yay for reusability!

It also means that if later on I decide that popups are bad practice, (which they are!) and that I want to replace them with a lightbox style modal window, I can change:

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

to

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

and all my popups on my whole site are now working totally differently. I could even do feature detection to decide what to do on a popup, or store a users preference to allow them or not. With the inline onclick, this requires a huge copy and pasting effort.


It's not good for several reasons:

  • it mixes code and markup
  • code written this way goes through eval
  • and runs in the global scope

The simplest thing would be to add a name attribute to your <a> element, then you could do:

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

although modern best practise would be to use an id instead of a name, and use addEventListener() instead of using onclick since that allows you to bind multiple functions to a single event.


With very large JavaScript applications, programmers are using more encapsulation of code to avoid polluting the global scope. And to make a function available to the onClick action in an HTML element, it has to be in the global scope.

You may have seen JS files that look like this...

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

These are Immediately Invoked Function Expressions (IIFEs) and any function declared within them will only exist within their internal scope.

If you declare function doSomething(){} within an IIFE, then make doSomething() an element's onClick action in your HTML page, you'll get an error.

If, on the other hand, you create an eventListener for that element within that IIFE and call doSomething() when the listener detects a click event, you're good because the listener and doSomething() share the IIFE's scope.

For little web apps with a minimal amount of code, it doesn't matter. But if you aspire to write large, maintainable codebases, onclick="" is a habit that you should work to avoid.