Category Archives: JavaScript

Free Web-Development Course

I have recently started offering a free web-development course both in person and online. The title of this meetup is “Home-Brew Web Development” and it takes place every Thursday evening at 7:30pm Easter Standard Time (unless otherwise stated). Each meetup is streamed live online at http://learn.sampson.ms, and archived on YouTube immediately afterwards.

We will start by learning HTML, followed by CSS. Eventually we will get into more advanced topics but I plan to keep it simple for now. This course is intended for those who have zero (or very little) experience in web-development, but are interested in it as a hobby, or a career-opportunity.

If you would like to receive regular updates regarding this course, future meetings, and more, you may subscribe to the newsletter via the link below. If at anytime you wish to stop receiving emails and stop attending the meetup, you’re totally free to go – it’s your call :)

Subscribe: http://eepurl.com/u_A61
Episodes: http://www.youtube.com/playlist?list=PL3IYnZmsleiXRVk1G-dcX4AJ_9kcSIO99

Sorting Arrays in JavaScript, from the Inside-Out.

Every now and then I come across questions on StackOverflow that require me to do a bit of thought-work. This particular question was asking to to take an array, such as [‘a’,’b’,’c’,’d’,’e’], and flip it inside out, so that it becomes [‘c’,’d’,’b’,’e’,’a’]. I’m not a particularly mathematical person, so when I discover a difficult to discern pattern, I get excited – such was the case with the code below.

// Arrays to sort
var data = ["a","b","c","d","e"],
    info = ["a","b","c","d"];

// Sort array from inside-out ['a','b','c','d','e'] 
// Resulting in the following ['c','d','b','e','a']
function gut (arr) {
    
    // Resulting array, Counting variable, Number of items, 
    // initial Location
    var out = [], cnt, 
        num = arr.length, 
        loc = Math.floor(num/2);
    
    // Cycle through as many times as the array is long
    for (cnt = 0; cnt < num; cnt++)
        // Protecting our cnt variable
        (function () {
            // If our array has an odd number of entries
            if (num % 2) {
                // If on an odd iteration
                if (cnt % 2) {
                    // Move location forward
                    loc = loc + (+cnt); 
                } else {
                    // Move location backwards
                    loc = loc + (-cnt);  
                }
            // Our array has an even number of entries
            } else {
                // If on an odd iteration
                if (cnt % 2) {
                    // Move location backwards
                    loc = loc + (-cnt);
                } else {
                    // Move location forwards
                    loc = loc + (+cnt);
                }
            }
            // Push val at location to new array
            out.push(arr[loc]);
        })()
            
    // Return new array
    return out;
    
}

// Test with two arrays; even and odd sizes.
console.log(gut(data), gut(info));​

Which results in the following output:

["c", "d", "b", "e", "a"]
["c", "b", "d", "a"]

Perhaps you will find some use for it.

Creating Your Own Custom jQuery Filters

Chances are you have probably used custom filters in jQuery from time to time to save on verbose selectors. For instance, if we wanted all of the buttons, selects, inputs, and textareas within a form we could do the following:

$("button, textarea, input, select", "#myForm");

You can see how that quickly piles up and gets a bit heavy. jQuery natively provides us with the :input filter which grabs all form elements:

$("#myForm :input");

While these both do the same thing, it’s far easier to call :input than it is to construct a large selector containing all of the particular form elements we can remember at the time. There is a bit of  a performance issue with things like :input though, since they have to cycle over all potential elements. That’s why it’s wise to limit our load by providing some context, in this case we’re looking only within #myForm.

While we can do a lot with what jQuery brings out-of-the-box, we’re capable of doing so much more using some of the tools it provides us with.

You’ve likely used .filter to sift through your elements before applying some effects:

$("div").filter(":visible").hide();

The filter method can take a string expression like :visible and determine which of the div elements meet its demands, and which don’t. Those that don’t will be dropped, and all remaining will have .hide called against them. This method can take a function as well:

$("div").filter(function(){
    return $(this).text() === "Foobar";
}).hide();

Here we are manually sifting through the elements based upon some examination of their properties. We return true or false, depending on whether the current element being evaluated has the text “Foobar” or not. This solution isn’t very flexible though, what if I wanted to check different things for different strings?

Fortunately jQuery exposes itself in such a way that we can extend its base filters and add our own.

Our focus from here will be on $.expr[“:”]. Within the jQuery function ($) is an object called expr. This object has objects within, one of which is called “:”. This object is where we will place our new method, and provide the necessary functionality to determine which elements pass, and which fail.

$.extend($.expr[":"], {
    exactly: function(){
        return true;
    }
});

With nothing more than the above, we can already use our filter:

$("div:exactly");

Granted, it doesn’t do anything, but it doesn’t blow up in our face either! As is the case with most callback methods, the element currently being handled is referred to as this. With that, we could already perform some logic:

$.extend($.expr[":"], {
    exactly: function(){
        return $(this).text() === "Foobar";
    }
});

Of all the div elements we’re cycling over, only those whose text content loosely equals “Foobar” will be kept, while all others are discarded. But again, who wants to hard-code “Foobar” into the definition of the filter? Wouldn’t it be better if our filter worked like :contains in that it took some parameters?

It is at this point we need to look at the arguments passed to our function. We can do so by logging the arguments object from within:

$.extend($.expr[":"], {
    exactly: function(){
        console.log( arguments );
    }
});

$("div:exactly");

In our console we find the following:

[<div>​Hello World</div>​,   0, Array[4], NodeList[3]]
[<div>​Hello, World</div>​,  1, Array[4], NodeList[3]]
[<div>​Hello, World.</div>​, 2, Array[4], NodeList[3]]

My selector evaluated three div elements. The first argument passed to my function is the element itself. The second is the index of the element. Third is an array of details about the selector itself (more about that in a minute), and the last item is a NodeList of all elements being evaluated.

In this particular instance, our selector array looks like this:

[":exactly", "exactly", undefined, undefined]

We see it has a reference to the filter, the term used in the filter, and then two undefined values. If we were to modify our filter a bit to accept a parameter, we would see the following:

$("div:exactly(Foobar)");
[":exactly(Foobar)", "exactly", "", "Foobar"]

The first value is our entire selector. The second is our filter name, third in this case is empty (though if we wrapped our term in single quotes, this entry would be a single quote as the outer-most single-quotes would be removed from the last item in this array), and last is the actual parameter passed in. Armed with this knowledge, we can then finish our custom filter:

$.extend($.expr[":"], {
    exactly: function( element, index, details, collection ){
        return $(element).text() === details[3];
    }
});

At this point, we can now select any element based on its text value:

$("div:exactly(foo), p:exactly(bar)");

We now have a reusable solution to a common task.

Abusages in JavaScript

Upon reading a recent blog entry by Brendan Eich (creator of the JavaScript language), I found myself falling under a bit of conviction when he described a popular use of || (OR) and && (AND) as an “abusage”.

I also agree…that the && line (!isActive && $parent.toggleClass(‘open’)) is an abusage, allowed due to JS’s C heritage by way of Java, but frowned upon by most JS hackers; and that an if statement would be much better style.

Now this word hardly requires defining for most of us, but for everybody else it is described on Wictionary as improper or incorrect use of language.

If you’re not familiar with using || and && in the aforementioned manner, here’s the reasoning behind it. It acts as something of a short-cut if-statement. In fact, as Brendan said “an if statement would be much better style.” Let’s compare the two:

!isActive && $parent.toggleClass( 'open' )

In this line, if everything to the left of the operator evaluates to true, the “argument” to the right is also evaluated. Of course this behavior is being tricked into actually executing a method if the argument to the left, treated as a condition all by itself, evaluates to true. As an if statement it would look like this:

if ( !isActive ) $parent.toggleClass( 'open' )

This makes sense to the majority of developers. It actually reads the way in which we expect it to behave.

Similar to the if statement, if our “condition” (in this case, everything to the left of &&) evaluates to false, only then will the statement on the right be evaluated, invoking the toggleClass method.

The && and || operators perform what is known as short-circuit evalutation. The second argument is only evaluated if the first wasn’t sufficient to determine the value of the expression. Contrary to &&, || will only evaluate the argument to the right if the argument on the left evaluates to false.

I really only learned about this trick of the JavaScript language in the last year or so. I have been using && and || in expressions for years, but never thought to bring them outside the parens.

Lately I have been using these within things like feature-detection:

!!foo.classList || loadScript( 'classListPolyfill.js' );

Using double-negation (!!), we can convert an undefined value into a boolean false. So if the classList member is not found, the argument on the left evaluates to false, which in turn causes the “argument” on the right to be executed. We hi-jack this behavior to load a polyfill script for the classList member. You could modify this to use && instead, and save a char, however “OR” sounds more appropriate.

Bottom line, if Brendan Eich is right (and I suspect he of all people would be), it’s far wiser to just stick within the design and intended use of the language:

if ( !foo.classList ) {
  loadScript( 'classListPolyfill.js' );
}

There goes another super-cool esoteric trick of the masters. Guess I’ll find my seat on the bench and wait to be picked for dodge-ball.

Sometimes jQuery is (not) the Answer

It’s difficult to say, as much as I love jQuery I must admit that it is at times the wrong route to take when addressing a problem.

While looking over a few questions on StackOverflow today I came across a poster who was seeking to modify the width of all nested elements within a container – he naturally thought jQuery would be a good, simple solution – and it is. But while it may be simple, it’s wrong in this case.

Rather than coming right out and answering with something like:

$("#container").find("*").width("100%");

I instead took just a moment to whip up a test case on http://jsperf.com (great site for testing the performance advantages of one method over others.) Just as I had suspected, jQuery would be slower than raw JavaScript – much, much slower.

var i,
    container = document.getElementById("container"),
    tags = container.getElementsByTagName("*"),
    total = tags.length;

for ( i = 0; i < total; i++ ) {
  tags[i].style.width = '100%';
}

This simple block does the same thing as the aforementioned jQuery code, but it’s much faster. In fact, in the time it takes the jQuery code to perform 20k operations, the raw JavaScript code performs nearly 300k!

You can see this particular performance test online at http://jsperf.com/resizing-children.