Click here to Skip to main content
15,883,959 members
Articles / Programming Languages / Javascript

How jQuery and “unobtrusive JavaScript” Can Be Poisonous

Rate me:
Please Sign up or sign in to vote.
4.64/5 (4 votes)
26 Jun 2012CPOL7 min read 34.3K   4   17
Stop demanding that the UI be completely separated from logic. Without the use of significantly robust frameworks, I simply do not think that this is achievable.

If you have been developing websites at all in the past 6 years, then chances are you have been using (or been exposed to) the jQuery library. In fact, it is used by over half of the top 10,000 web sites in the world!

Se before I start an unwarranted flame-war:

I love and use jQuery almost every day, and think it is a freakin’ fantastic library.

Seriously. It is possibly the most important ~9,400 lines of JavaScript ever written.

So What Am I Going On About Then?

The thing is, like for any great tool, people start to (mis-)use the crap out of it, even if it is not the right tool for the job. I’m guilty of it too. It is far too easy for a project to start out small, where the client-side interaction is simple and basic enough to be easily accomplished with a couple of lines of jQuery/JavaScript. Then, in a short time, some more features are added. Slowly your jQuery code becomes more and more spaghetti-like.

If you allow this to happen, this is where things get poisonous. If you work in a team of developers, you can quickly become the ONLY person who can even look at your code. Even if you can look at it, the chances of you being able to quickly refactor it diminish by the day.

jQuery is Not a Framework. It’s a Library.

The problem is: people use it like a framework. jQuery is intended to allow reliable manipulation and traversal of the DOM. It is NOT intended to provide a foundation for significant client-side interaction or client-side manipulation.

When Used Carelessly, jQuery Code Can Become Hopelessly Unmaintainable

spaghetti code is not fun

The primary issue here is with jQuery’s CSS Selectors, and over-using them to the point where, a simple change in your HTML can bring the whole house of cards down. This is because they make getting something to work FREAKIN’ EASY. Let’s look at a scenario:

Let’s say I have the following in my HTML view:

HTML
<div class="cool-content-wrapper">
    <a href="#" class="be-cool">Do Something Cool!</a>
    <div class="cool-content">
        Hello World!
    </div>
</div>

And then in jQuery, I write the following code (and of course, like EVERY OTHER piece of JavaScript I write, I am going to stick it in my document.ready callback function):

JavaScript
$(function () {
    $("a.be-cool").click(function () {
        alert($(this).parent().children(".cool-content").text());
    });
});

Now I got this simple “Hello World”-ish app working in a line or two of code. I’m feeling pretty good about myself. Check in my code – onwards and upwards.

Here’s the problem: Let’s say 2 months down the road, I ask my designer/front-end dev to re-do some of the CSS for the page that contains this HTML. It needs a facelift. The page has been working without problems for months, so I think “Hah, I’m sure my designer can play around with it without affecting any of the code!”

In this facelift, something might come up to where it just makes more sense to move that anchor tag outside of the wrapper div:

HTML
<a href="#" class="be-cool">Do Something Cool!</a>
<div class="cool-content-wrapper">
    <div class="cool-content">
        Hello World!
    </div>
</div>

All of a sudden, my app is broken. Worse though – it’s broken in a way which won’t trigger any errors whatsoever – jQuery doesn’t know that what it’s doing is wrong. It’s just doing what it’s told. Now please don’t tell me how I could have written the JavaScript differently to where it wouldn’t have failed. That isn’t my point. My point is that this isn’t the only scenario where these selectors could become faulty. And no matter how good of a developer you are, you cannot predict the changes you will need to make 2+ months ahead of the time you are first writing the code.

jQuery is NOT Unobtrusive JavaScript. At Least Not How I See It

You may have heard that jQuery allows for you to create “Unobtrusive Javascript”. This term was basically created to combat code such as the following:

HTML
<a href="#" onclick="foo(this);">Do Something Cool!</a>

Or something even uglier:

HTML
<a href="#" onclick="if(someLogicIsMet) { foo(this);} else { bar(this);}">
    Do Something Cool!
</a>

Basically, here we are just injecting straight up JavaScript into HTML attributes. Yeah. Doesn’t seem like the best of solutions.

People were basically doing this left and right a couple of years ago, and then jQuery came along, and a light lit up in everyone’s heads:

JavaScript
<a id="coolButton" href="#">Do Something Cool!</a>
<script type="text/javascript">
    $("#coolButton").click(function () {
        if (someLogicIsMet) { foo(this); } else { bar(this); }
    });
</script>

Hey! Now my HTML looks nice and pretty! All of my UI logic is nicely tucked away into a <script> tag (or better yet, a .js file) and now I have reached Developer Zen!

Although this example is pretty bulletproof, let’s go back to the samples above. What makes these different? The answer is not much – but just enough. Basically the primary difference in my mind is that most people look at an id of an HTML tag as something more or less permanent. When you start using the CSS Class Selectors instead of the ID selectors, your logic is starting to creep its way into the territory of the “UI”. If I’m a designer, chances are I’m not going to touch an id attribute.

The class attributes however, seem like fair game. They are primarily intended for CSS… so if I’m changing up the CSS and I determine I no longer need that CSS class, or that moving it outside of its parent div will not affect the CSS attributes that have been applied thus far… what’s the harm? By the time you actually need to do this, you have probably followed best practices and completely pulled out all of your JavaScript into a separate, minified file. Although this is great for page-load times, it sure makes it hard for me to remember that the CSS/HTML that I am refactoring is possibly going to break all my code.

Bottom line: jQuery cannot, and will not, ever separate itself from the HTML. You can pull out the logic, and have it contained inside an external js file. But that file is infested with dependency after dependency and is intimately coupled with the view. Unless you use a very strict limited subset of jQuery, there is no easy way out of this. This is worse than “obtrusive” JavaScript… this is SNEAKY JavaScript. Next to littering your code with comments and/or being part of the .001% which has managed to successfully implement a JavaScript Unit-Testing framework (at which point, I will throw a wild guess that this article is absolutely worthless to you and not providing you with any new insights), there is no easy way to determine if modifying your HTML view will break your UI logic.

So What’s the Solution?

If you want my take on it all, the solution is to stop demanding that the UI be completely separated from logic. Without the use of significantly robust frameworks, I simply do not think that this is achievable.

And why should it be?

Your HTML is no longer just presenting marked-up/formatted text to the client. That’s the whole point of “client-side interaction”. You are introducing the ability to *interact* with the HTML. The best solution I can come up with is to do the following:

  • Don’t mix and match CSS-intended classes with jQuery-intended classes.
  • Limit the amount of complex css-selectors used in jQuery event declarations (i.e., $(“.class1 .class2 > .class3″) or something similar)
  • Care less about whether or not your HTML is “pure” and more about whether or not your code will be maintainable
  • Expand your horizons into one of the many JavaScript Frameworks available, and utilize jquery, rather than abuse it.

The last item there is important. In the last few years, several awesome JavaScript frameworks have come out (mostly of the MVC or MVVM variety). Every web developer should explore these options and learn more about what tools (other than jQuery) are out there. One of my next few posts will be about some of these frameworks, and what my thoughts are on them. The link above does do a good “first-glance” survey of 10 different frameworks though, and will be a good starting point for anyone wanting to learn more.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder
United States United States
My name is Leland Richardson. I love learning. At the time of writing this I am 23 years old and live in Houston, TX. I was born in West Palm Beach, Florida, grew up in St. Louis, Missouri, and went to school in Houston, Texas at Rice University.

At Rice I received two degrees: one in Physics and one in Mathematics. I love both. I never received any formal education on Computer Science, however, you will find that most of this blog will be about programming and web development. Nevertheless, I think being a good programmer is about being good at learning, and thinking logically about how to solve problems - of which I think my educational background has more than covered.

Since high-school, I had found that the easiest way to make money was by programming. Programming started off as a hobby and small interest, and slowly grew into a passion.

I have recently started working on a new startup here in Houston, TX. I wont bore you with the details of that just yet, but I am very excited about it and I think we can do big things. We plan to launch our project this year at SXSW 2013. What I will say for now, is that we would like to create a company of talented software developers who are similarly ambitious and want to create cool stuff (and have fun doing it).

Comments and Discussions

 
SuggestionFood for thought...thank you Pin
kirredlen24-Apr-13 1:38
kirredlen24-Apr-13 1:38 
GeneralGood read Pin
Flamewave43-Jul-12 6:06
Flamewave43-Jul-12 6:06 
GeneralRe: Good read Pin
Leland Richardson3-Jul-12 6:16
Leland Richardson3-Jul-12 6:16 
SuggestionNice article... Pin
satish.kotha29-Jun-12 8:36
professionalsatish.kotha29-Jun-12 8:36 
GeneralRe: Nice article... Pin
Leland Richardson2-Jul-12 4:48
Leland Richardson2-Jul-12 4:48 
Questionyes and no Pin
kkkeef27-Jun-12 21:20
kkkeef27-Jun-12 21:20 
AnswerRe: yes and no Pin
Leland Richardson2-Jul-12 4:46
Leland Richardson2-Jul-12 4:46 
GeneralMy vote of 5 Pin
Justin Cooney27-Jun-12 3:59
Justin Cooney27-Jun-12 3:59 
GeneralRe: My vote of 5 Pin
Leland Richardson2-Jul-12 4:41
Leland Richardson2-Jul-12 4:41 
GeneralMy vote of 1 Pin
paulcman27-Jun-12 2:29
paulcman27-Jun-12 2:29 
GeneralRe: My vote of 1 Pin
Leland Richardson27-Jun-12 4:39
Leland Richardson27-Jun-12 4:39 
QuestionBravo ! Pin
Nicolas Dorier26-Jun-12 11:38
professionalNicolas Dorier26-Jun-12 11:38 
AnswerRe: Bravo ! Pin
Leland Richardson26-Jun-12 14:20
Leland Richardson26-Jun-12 14:20 
GeneralNot really... Pin
Vitaly Tomilov26-Jun-12 9:49
Vitaly Tomilov26-Jun-12 9:49 
GeneralRe: Not really... Pin
Leland Richardson26-Jun-12 10:02
Leland Richardson26-Jun-12 10:02 
GeneralRe: Not really... Pin
Vitaly Tomilov26-Jun-12 10:11
Vitaly Tomilov26-Jun-12 10:11 
GeneralRe: Not really... Pin
Leland Richardson26-Jun-12 10:18
Leland Richardson26-Jun-12 10:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.