jQuery Is not the answer


Edward Kim
@edwardjkim

jquery is everywhere (almost)


56% 
of all websites


92%
of javascript websites

Source: W3Tech

A common pitfall



I want to show/hide content when a user clicks on a link
"Nice that was pretty easy!"

I want to show data depending on what the user inputs
"Not too bad"

Now I want to let users manipulate the data
"This is getting harder but I'll keep going because I'm really good at jQuery."






Data - View - logic

storing data in the dom



As humans, it's easy to process data in this form
But for machines, it actually takes a lot of work to extract the data and start computing

A simple example



Sort this table by the price of beer

The Html


We get HTML for each table row from the server. 
Each table row has the class "bar".

<table>
...stuff...
    <tbody>
        <tr class="bar">
            <td class="name">McGinty's Public House</td>
            <td class="price">$4.00</td>
            <td class="address">911 Ellsworth Drive</td>
        </tr>
        ...more rows with class "bar"...

Sorting ain't easy


sortByPrice = function(a,b) {        return $(a).children('.price').html() >        $(b).children('.price').html() ? 1 : -1;
}

bars = $(‘.bar’) //bars is now an array of <tr> elements
bars.sort(sortByPrice); //bars is now a sorted array of <tr> elements
Now you have to find the parent <tbody> element and rearrange the rows.

Manipulating the DOM



$.each(bars, function(index, bar) {
    $('#bar-table').children('tbody').append(bar); // Very Bad!!!
}); 

The whole solution












Source: Stack Overflow

$(document).ready(function() {
    $('table.sortable').each(function() {
        var $table = $(this);
        $('th', $table).each(function(column) {
            var $header = $(this); 
            $header.click(function() {
                var rows = $table.find('tbody > tr').get();
                rows.sort(function(a, b) {
                    var keyA = $(a).children('td').eq(column).text().toUpperCase();                    var keyB = $(b).children('td').eq(column).text().toUpperCase();
                    if(keyA < keyB) return -1;
                    if(keyA > keyB) return 1;
                    return 0;
                });
                $.each(rows, function(index, row) {
                    $table.children('tbody').append(row); // Very Bad!!!
                }); 
            });
        }); 
    });
})












Not at all obvious how these are connected <script>
<html>








A growing rift between view and logic


 

WHAT ABOUT COMPLEX VIEWS

 

   Bars within x miles of the Civic Center




jquery is not a framework

MV* to the rescue


Data - View - Logic

Model - View - Controller (MVC)
Ex. Backbone.js


Model - View - ViewModel (MVVM)
Ex. Knockout.js

Table Sorting in knockout

<table>
...stuff...
    <tbody>        <!-- ko foreach: sortedBars -->
        <tr class="bar">
            <td data-bind="text: name" />
            <td data-bind="text: price" />
            <td data-bind="text: address" />
        </tr>
        <!-- /ko -->
function sortByPrice (a,b) {    	return a.price > b.price ? 1 : -1;}barData = [{name: "Piratz Tavern", price: "3.50", ... }]
sortedBarData = barData.sort(sortByPrice)viewModel.sortedBars = ko.observableArray(sortedBarData);




When performance matters

remember this?


$.each(rows, function(index, row) {
    $table.children('tbody').append(row);
}); 
Heavy DOM manipulation takes a lot of work. Compare this to pure javascript, and a framework like knockout.js

[Benchmark table]

FILE SIZe

OK, jquery does have good parts


  • Browser compatibility
  • Ajax
  • Handling Events

Great Use Cases Include
  • Small Self-contained widgets (jQuery UI)
  • Scraping Websites
  • Rapid Prototyping (arguably)

In Summary



jQuery is not a framework
It can be slow

It's a great tool. Just be careful not to overuse it.

using the dom as a data store


Click on a link, it appends content to the page
I know the content is expanded because I can select an element that wasn't there before.

Essentially, I'm using the current state of my view to dictate logic.

This is brittle 

Copy of jQuery is Not the Answer

By Edward Kim

Copy of jQuery is Not the Answer

  • 679