Daniel Matthew HTML, CSS, and JavaScript developer

Check whether a DOM element exists using jQuery

A straightforward little post: if you want to detect whether a DOM element actually exists on the page (perhaps you’re flying in the blind), you can write if ($('selector').length) { // Foo }. If the element is present, it’ll evaluate to true and you can work from there.

JavaScript's Ternary Operator

When you've been writing code for a good while, you start looking at ways to speed up the process. Perhaps the most obvious method to achieve this is to write fewer lines of code.

A typical if/else statement looks like this:

var foo = 10,
    bar = 20,
    baz;

if (foo > bar) {
  baz = foo;
} else {
  baz = bar;
}

console.log(baz); // 20

Look at that: five lines of code. We can do better than that, right?

Right!

JavaScript offers a ternary operator that takes three values: condition ? expr1 : expr2. The above code can be condensed to the following.

var foo = 10,
    bar = 20,
    baz;

baz = foo > bar ? foo : bar; 

console.log(baz); // 20

What we’re saying is that if foo is greater than bar, baz is assigned the value of 10. If not, baz is 20.

Personally, I’ve found that a major drawback of using syntax like this is that the code becomes harder to parse when reading through it. Your mileage may vary, but just like omitting the braces of single-line if statements, it takes just that extra beat of brain-power to comprehend.

Each, Map, and Reduce

Functional programming (FP) aims to create predictable code by eliminating so-called side effects, bringing with it confidence that the same code with the same arguments will produce the same results. In order to achieve this, developers rely on higher-order functions: functions that operate on other functions.

JavaScript provides the developer with a number of useful functions that can be used to apply FP principles to their development.

forEach()

forEach() takes an array, iterates over its values and applies the specified function on them. It can be considered an abstracted version of the basic for loop: we don’t define a counter, check the length of the array, tell it how to increment (or decrement, for that matter), nor have to define a new variable within the loop body to store the current element.

var foo = [
  'Tom',
  'Dick',
  'Harry'
];

foo.forEach(function(name) {
  return name + ' smells';
});

While the applied function can be created on the spot, we can also provide a function that has been written earlier in the hopes of adhering to the principle of DRY.

forEach() (and the functions mentioned below) were ‘only’ standardised in 2009, so aren’t available in older browsers. Should you rather not write a polyfill yourself, lodash (or Underscore) provide an interface to the same functionality:

var foo = [
  'Tom',
  'Dick',
  'Harry'
];

_.each(foo, function(name) {
  return name + ' smells';
});

Interestingly, Ben McCormick tells us that the two libraries are both faster than their native counterparts in this case:

A little research indicates that this is because native functions optimize for sparse arrays and have more weird corner cases that they handle. In any case, the performance difference is pretty startling across the board.

While the native implementation is currently only available on arrays, lodash’s implementation is designed to operate on any kind of collection, including object literals and NodeLists.

map()

The map() method takes an array, iterates over its contents, applies a function to all of its elements, and returns a new array with the transformed values.

var foo = [
  'Tom',
  'Dick',
  'Harry',
];

// Native
var bar = foo.map(function(name) {
  return name + ' smells';
});

// lodash
var bar = _.map(foo, function() {
  return name + ' smells';
});

This helps streamline the process of avoiding ‘side effects’ - the function isn’t altering our original array, so it can be used again without mishap.

reduce()

When we want to get just a single value from an array, we can turn to reduce(). This method aggregates all values in a collection and returns a single value from them: whether that be a miniumum, maximum, average, or what-have-you.

reduce() takes a transformative function, and an intial value it should start computing with:

var foo = [
  {name: 'Tom', age: 20},
  {name: 'Dick', age: 30},
  {name: 'Harry', age: 40}
];

var totalAge = function(result, person) {
  return result + person.age;
};

// Native
var total = foo.reduce(totalAge, 0); // 90

// lodash
var total = _.reduce(foo, totalAge, 10); // 100 - we started with 10 and continued summing from there.

Conclusion

The functions featured above are useful additions to a developer’s toolkit. That these are higher-order functions means that they allow developers to write code that is simple to comprehend. There is no mess of code dealing with initialising loops to wade through. As these functions work on the output of other functions, they can be chained together quite trivially. Here’s lodash’s example for its .chain() function:

var users = [
  { 'user': 'barney',  'age': 36 },
  { 'user': 'fred',    'age': 40 },
  { 'user': 'pebbles', 'age': 1 }
];

var youngest = _.chain(users)
  .sortBy('age')
  .map(function(chr) {
    return chr.user + ' is ' + chr.age;
  })
  .first()
  .value();
// → 'pebbles is 1'

Straightforward, self-documenting code.

Using JavaScript's bind() function

Since it was introduced in 2009’s ECMAScript 5 (ES5) specification, all functions have the bind() method. Using it creates a new function that calls the original with some arguments already fixed. This is known as a "partial function application".

Using bind to set parameters

Partially applying a function using bind() allows us to fill in arguments before the function is called. In the following example, bind() is used to create a new function that takes add(), but only requires a single parameter: x is always going to be 1:

function add(x, y) {
  return x + y;
}

var plus1 = add.bind(null, 1);
console.log(plus1(5)); // 6

Using bind to set this

bind() can also be used to allow the developer to specify the context in which this must be used. In the example above, we passed null. In the next, we don’t pass any additional arguments, but provide the function an object. As we learnt previously, this is bound explicitly when set this way.

function foo(something) {
  console.log(this.a, something);
  return this.a + something;
}

var obj = {
  a: 2,
};

var bar = foo.bind(obj);

var b = bar(3); // 2 3
console.log(b); // 5

this and that in JavaScript

When looking at code written by others, you may wonder why JavaScript developers will often alias this as that, or self, within a function. Why is this? Surely this always refers to the current object?

Short story: nope.

What’s this?

Unlike other languages where it refers to values stored in instance properties, the this keyword is dynamically bound based on how a particular function is executed. Because of its shifting nature, it can be tricky to keep track of what this might be referring to when it is called. With a little understanding of the rules behind this, we can be more confident when writing our code.

There are four rules that help us figure out what this may be at a particular point in time, and these rules are based on the call-site of the function.

1: Default Binding

When our function is invoked of its own accord, ala:

function foo() {
  console.log(this.a);
}

var a = 2;

foo(); // 2

The call to this.a resolves to the global variable of the same name. If we were running in strict mode - and you should - we would find that it would be undefined:

function foo() {
  console.log(this.a);
}

var a = 2;

foo(); // 'this' is undefined

2: Implicit Binding

When calling a function as an object method, its call site now has some context and the object in question should be used for the function’s this binding.

function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
  foo: foo
};

obj.foo(); // 2

3: Explicit Binding

We can use the call() and apply() utilities to force a function to use a particular object for its this binding. For both utilities, the first parameter is the object to use. As we’ve discovered previously call() takes a list of parameters, while apply() is given an array as its second argument.

function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
};

foo.call(obj); // 2

Hard Binding

Both implicit and explicit binding lose their this binding when passed around. The following pattern helps ensure that this doesn’t happen:

function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
};

var bar = function() {
  foo.call(obj);
};

bar(); // 2
setTimeout(bar, 100); // 2

The new bar() function calls foo() with this bound to our object. bar() can be passed around, as it is to setTimeout(), and yet this remains 2.

It might get a little tiresome wrapping functions for this purpose, so ES5 (supported natively in IE9+, or with ES5-shim) gives us bind(): a utility that returns a new function that calls the original, with this set as required.

function foo(something) {
  console.log(this.a, something);
  return this.a + something;
}

var obj = {
  a: 2,
};

var bar = foo.bind(obj);

var b = bar(3); // 2 3
console.log(b); // 5

4: new Binding

When using new to create a new object, the new object is set as the this binding.

function foo(a) {
  this.a = a;
}

var bar = new foo(2);
console.log(bar.a); // 2

So, if the function is called:

  • with new, this is the new object;
  • using call, apply, or bind, this is the specified object;
  • as it being a method of an object, this is that object;
  • in standard execution, this is either the global object, or will be undefined if using strict mode.

Why that, then?

Each function call gets its own this binding. When a function is executed inside another, we no longer have access to the original this value. By aliasing it as that or self at the top level, we can retain a reference to the original value and make it visible to inner functions.

As for the reasoning behind this convention, Douglas Crockford states that:

…This is a workaround for an error in the ECMAScript Language Specifications which causes this to be set incorrectly for inner functions.

While it’s a useful trick to have in the toolbox, JavaScript does give us utilities to avoid having to use it in the first place. We can take advantage of the functionality JavaScript gives us with call(), apply(), and bind() in order to explicitly tell a function the context it will be running in.

setTimeout and setInterval

JavaScript features a couple of useful utilities that allow the developer to schedule code to run outside of the normal execution flow.

setTimeout

In order to run a function after a specific delay, we use setTimeout():

function doSomething(message) {
  console.log(message);
}

var myTimeout = setTimeout(doSomething, 2000, "lol");

// Two seconds later...
// lol

Timeouts can be cancelled using clearTimeout() and passing the ID of the timeout in question. In the above example, to prevent our applicating from printing lol, we could set up a button which called clearTimeout(myTimeout).

setInterval

If you want to call a function repeatedly, setInterval() is the more appropriate tool. It looks very similar:

function doSomethingElse(message) {
  console.log(message);
}

var myInterval = setInterval(doSomethingElse, 5000, "See you in five...");

// Every five seconds...
// See you in five...

As with timeouts, we can run clearInterval() to call a halt to proceedings when we are done with it.

Debouncing

Imagine a searchbox that offers suggestions as you type. On each keydown event, a function is run that makes a network request. If the user enters a long query quickly, the browser (and remote server!) may quickly become overwhelmed and end up feeling unresponsive.

To overcome this, we can implement setTimeout() in order to debounce the event: we prevent it from happening too often. Instead of calling the function on each keypress, we wait for an opportune moment - perhaps a slight pause. When events occur closer than our timeout delay, the timeout from the previous keypress is cancelled and a new one is executed.

var myTextBox = document.querySelector('[type="search"]');
var myTimeout;

myTextBox.addEventListener("keydown", function() {
  clearTimeout(myTimeout);
  myTimeout = setTimeout(function() {
    // Query remote server
  }, 500);
});

Implementing Responsive Images

Updated 26/06/2015: The sizes attribute is no longer optional if you want your code to validate.

I’m hoping that you’ll notice the site - particularly my work section - is feeling a little snappier today: that’s because I took it upon myself to implement a solution for responsive images.

Take a look at this screenshot (also a responsive image, fact-fans): Before: Screenshot showing the network tab within Chrome's Developer Tools

Chrome’s Developer Tools are telling us that a request to /work had the browser download 3.4 MB over 13.77 seconds - on a fast ADSL connection. That’s pretty bad news for a visitor using a mobile phone on a cellular connection: whether it be the time needed for the page to finish loading, or if their provider imposes a data cap.

I have a confession: I was being pretty lazy. The images presented were simply screencapped in OS X and uploaded. I didn’t resize them or convert them from PNG-24 to a more pallatable format for the web. It’s not like I needed the transparency! In fact, I could probably go further: I could crop out the drop-shadow and browser chrome, and implement those additions with CSS.

There are a few options open to a developer wishing to implement responsive images:

The srcset attribute

srcset allows the developer to provide the browser with multiple resolutions of the same image.

<img srcset="/public/img/build/ribbonworks-new-full.jpg 1307w,
/public/img/build/ribbonworks-new-med.jpg 654w,
/public/img/build/ribbonworks-new-small.jpg 327w" 
src="/public/img/build/ribbonworks-new-full.jpg" 
alt="Ribbonworks.co.uk" />

The srcset attribute is simply a comma-separated list of URIs and a “width descriptor”, which is used by the browser as part of its decision-making process.

The sizes attribute

When I first wrote this entry, I’d neglected to mention this attribute as I hadn’t considered it to be a major requirement. After all, with my single-column layout I’m happy for my images to always fill the available space.

But what if you’re not? Try this:

<img srcset="/public/img/build/ribbonworks-new-full.jpg 1307w,
/public/img/build/ribbonworks-new-med.jpg 654w,
/public/img/build/ribbonworks-new-small.jpg 327w"
sizes="(max-width: 30em) 100vw, (max-width: 48em) 50vw, 33vw" 
src="/public/img/build/ribbonworks-new-full.jpg" 
alt="Ribbonworks.co.uk" />

The sizes attribute tells the browser what portion of the viewport the author intends the image to assume at a given breakpoint. This is intended to prevent larger images being downloaded unnecessarily. By default - and why I’ve gotten away with it - it assumes the image will be 100vw.

In the above example, a viewport up to 30em in width will download the image that will fill the available space. After that, it’ll do the maths to figure out which image to display between 30 and 48em. And once again once that breakpoint has been passed.

The picture element

The new picture element in HTML allows the developer to implement ‘art-direction’: they can choose the image displayed at a particular breakpoint. My screenshots are all of a desktop browser. I could use the picture element to display these images as they appear on mobile, or tablet browsers. The syntax is a slight departure from using img:

<picture>
  <source media="(max-width: 36em)" srcset="/public/img/build/ribbonworks-new-mobile-full.jpg 1307w,
/public/img/build/ribbonworks-new-mobile-med.jpg 654w,
/public/img/build/ribbonworks-new-mobile-small.jpg 327w" />
  <source srcset="/public/img/build/ribbonworks-new-full.jpg 1307w,
/public/img/build/ribbonworks-new-med.jpg 654w,
/public/img/build/ribbonworks-new-small.jpg 327w" />
  <img src="/public/img/build/ribbonworks-new-full.jpg" />
</picture>

The developer provides source elements and an img. The browser evaluates the sources until the parameters provided in media attribute are true. The srcset from this source is then applied to the img.

Processing Images

The main obstable to implementing this isn’t browser support (there are multiple quality polyfills, such as Picturefill), but actually creating multiple versions of each of your images. I ended up using Photoshop and saving each file out at 50 and 25 percent. In doing so, I encountered its “Extract Assets” feature which would make the process a cinch - if its output matched my workflow. I’d looked at ways of automating it, and found several Grunt plugins, including grunt-responsive-images, though I got turned off at the need to install Imagemagick. Adding this functionality to a platform such as WordPress would be seemingly trivial - again, so long as a module such as Imagemagick is installed. WordPress already has the ability to process images and create multiple sizes for different roles.

Results

Simply converting my portfolio images to JPEG reduced the required bandwidth down to 1.5 MB: a 42% reduction. As Kevin Bacon would say: “a no-brainer”. By taking advantage of srcset and providing scaled-down versions of the images, the site loaded in just 2.66 seconds, and only transferred 522 KB: After: Screenshot showing the network tab within Chrome's Developer Tools

Worthwhile reductions methinks, and this just on a small site. If I were serving many thousands of impressions a day, I know that this would be one way to keep my bandwidth costs down, alongside making the browsing experience more tolerable for everyone.

last-child in CSS

The :last-child psuedo-selector allows the developer to target the last child element of its parent. But you need to qualify it with the element that you are targetting. Something that has caught me out in the past has been applying the selector to the parent itself:

/* Nope - this won't work and you'll feel silly */
ul:last-child {
  border-bottom: none;
}

It kind of makes sense, right? I want the last child of that unordered list. But no: pseudo-selectors, such as :last-child, :hover, and :checked work on the state of the specified element.

In the common scenario of wanting to style the last element in a list differently, you can use the following code example:

li {
  border-bottom: 1px solid #f3f3f3;
}

li:last-child {
  border-bottom: none;
}

When that list element finds itself as the :last-child of its parent, the browser will remove its border.

JavaScript's 'let' keyword

Good news everybody! ES6 (or ES2015) introduces the let keyword. This allows the developer to attach a variable to the scope of whatever code block - code between { and } - it resides in. Block scope rather than function scope!

JavaScript Constants

The new ES6 JavaScript standard finally allows developers to declare variables using the handy const keyword. This prevents the value from being reassigned - somewhat reassuring if that’s a requirement.

That said, values declared with const can still be modified after the fact: they’re not immutable. If you’re after that particular bit of functionality, you can still fall back on the .freeze property that objects have access to. If you’re using strict mode - and why not? - you’ll receive a TypeError, unless you look to see whether the object .isFrozen.