JavaScript Low Resolution Image Replacer

This is a handy, yet very simple, widget I was hacking on to replace loading or low resolution images with higher resolution ones once the document has finished loading.

How do it…

The widget is built using the jQuery plugin system and here is the complete code:

(function($) {
  var isLoaded = false,
    REPLACEMENT_CLASS = "replacement-class",
    REPLACEMENT_RCLASS = "replacement-rclass",
    REPLACEMENT_URL = "replacement-img",
    TIMER = 500;

  $(window).load(function() {
    isLoaded = true;
  });

  function replaceImages() {
    $(this).each(function(i, el) {
      var $el = $(el);
      $el.attr('src', $el.data(REPLACEMENT_URL));
      $el.addClass($el.data(REPLACEMENT_CLASS));
      $el.removeClass($el.data(REPLACEMENT_RCLASS));
    });
  }

  $.fn.replaceImages = function() {
    var $items = $(this);

    if (isLoaded) {
      $.fn.replaceImages = replaceImages;
      $items.replaceImages();
    } else {
      setTimeout(function() {
        $items.replaceImages();
      }, TIMER);
    }
  };
}(jQuery));

When adding images to the page, include a low resolution image in the src and a higher resolution image in the data-replacement-src:

<img src="<pathToALowResImage>"
    data-replacement-img="<pathToAHighResImage>"
    data-replacement-class="<classToAddOnReplacement>"
    data-replacement-rclass="<classToRemoveOnReplacement>"/>

Once imported, the plugin adds the method replaceImages to any jQuery collection:

$('img').replaceImages();
$('.myLowResImages').replaceImages();
$('#parentId img').replaceImages();
// ...

I have also created a little code pen to help illustrate (click rerun in the bottom right):

See the Pen JwpcB by Matt Snider (@mattsnider) on CodePen.


How it works…

With this plugin developers can load their webpages with lower resolution or loading images, and replace them with more detailed ones when the browser is available. By waiting for the window.onload event, we ensure that all images, scripts, css, and other files included with the page are loaded before we attempt to replace those images with larger, higher resolution ones. And because it’s written as a plugin, it works on any jQuery element collection.

There are three data- attributes that the plugin looks for. The most important is the data-replacement-img attribute which is required and should contain the high resolution image URL used to replace the low resolution one. The data-replacement-class can be set to any classes to add to the image after replacing the URL, and data-replacement-rclass can be set to any classes to remove after replacing the URL.

There’s more…

This plugin is useful as written, but it could benefit from an analysis of bandwidth (as mentioned in the Detecting Object Mutations by Counting Properties), with tiered higher resolution images based on the download speeds.

Network Information API Polyfill

One of the many new HTML5 APIs slowly being implemented by browsers is the Network Information API[2]. It exposes information about the type of network that the connecting device is using. In theory, this allows developers to optimize content around the connection speed of the user. However, as with most HTML5 APIs it is supported only by some browsers with/without prefixes, and has a legacy implementation, so a polyfill is useful when working with ...

Detecting Object Mutations by Counting Properties

Have you ever included a library and wonder, "how much did this library add to the window object", or passed an object into a function and asked yourself, "did that function modify my object"? Instead of reading the source code, this article shows a quick trick for answering these questions.

How do it…

For starters we need a function to count the number of properties on an object:
 function fnCountProperties(o) { var ...

Using Google Play Games on the Web

As many of you know, I now work for Google on the Play Games Team. We provide APIs for game developers, implementing useful features like leaderboards and achievements, so the developer doesn't have to. While many Android developers are using our services, adoption on the web could be better, so lets take a look at how to integrate the Google Play Games Services achievements into a web game.

Getting ready

Become a Google developer ...

Event Bubble & Capture Phases

One of the less understood, but powerful feature of browser events are their phases. According to the W3C level 2 spec there are three phases[1]: AT_TARGET=2, BUBBLING_PHASE=3, and CAPTURING_PHASE=1. Most browsers also implement a fourth phase[2]: NONE=0.

Getting ready

Just a quick note that everything discussed in this article is for modern browsers (all browsers except IE <9). Prior to IE 9, Internet Explorer used its own event system, instead of conforming ...

Passing Objects into addEventListener Instead of Functions

I was reviewing the browser event stack the other day and was reminded of a rarely used feature of addEventListener that allows developers to autobind the execution context object, instead of requiring a call to bind or using a library, that is worth sharing, if you weren’t already aware.

How do it…

Typically, when attaching an event, we write:
 var myObj = { handleEvent: function (evt) { // 'this' will be scoped ...

Using Promises to Cache Static AJAX JSON Data

This article showcases a useful caching strategy for static data that is fetch via AJAX. We will use jQuery to setup a promise and cache the data in the localStorage for subsequent page loads or data loads.

Getting ready

A modern web browser supporting localStorage and JSON. Also, a basic understanding of promises[2] is helpful.

How do it…

Here is the code:
 (function($) { var oKeyDeferredMap = {}; function fnReadData(sKey) ...

jQuery Function for Change Event and Delayed Keydown Event

In my experience, it is rare to assign only a change event to a text input, as any callback that would be executed for the change event should also be called on a key event as well, but with a slight delay (think how an autocomplete shows results as you type). This is a common pattern and I was surprised to not immediately find a jQuery plugin implementing it, so I decided to add one ...

Hoisting 102 - Examining a Global Context Hoisting Gotcha

In an earlier article we covered Variable Hoisting in JavaScript. At the time, I did not expect to face a hoisting related code bug so quickly. And given the circumstances of the bug, I expect it to be one of the most common hoisting problems, so I wanted to share it.

How do it…

Let’s jump right into the setup. You have a function that is defined in one JavaScript file (this file ...

jQuery Widget for Dynamic Input Helper Text

This is a proof of concept widget that I demoed for work. The desire is to update some text according to a regex and replacement, when an input field changes. This will allow developers to show a message and/or format the input value, so users understand they do not need to enter meta characters and see the result of their input (think phone or identification numbers). I built a simple jQuery plugin that can be ...