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 
Made with Slides.com