Extendify – Fixing Javascript objects in < 1K

It’s quite a lofty statement of mine to say that

1. Javascript is broken
2. I have fixed it. In <1K code compiled.

But I really like the way the library has come together for the 2.0 release. Sure, it adds to either the static Object or in the case of extend and getType, the object prototype (shock and horror), but theres a time and place for modifying built in prototypes – and this is the time and place when you want to add basic functionality to JavaScript.

I suggest you read the Getting Started section here on GitHub and let me know if it grabs you (or doesn’t).

https://github.com/jameswestgate/extendify

Responsive design – a simpler approach

If you’ve spent a bit of time working on responsive websites, you’ll have hit two problems or frustrations …

1. Scrolling up and down your css file comparing values between media query sections
2. Using mediaListeners, or checking body width just to work out what media query / display mode your page is currently using.

Inspired by libraries like moderniser or templates like html5 boilerplate that places classes in the head or body tag, I thought it would make life easier if you could place a class on an element (usually the body tag but any element is supported) and then go forth and style and code as usual.

The result is the mediaQuery plug-in for jQuery. If you want to use this plug-in you need to be comfortable with the following: you are already going to use jQuery, and you don’t mind your site being non-responsive for non-javascript users.

On the positive side, the plug-in includes polyfills for css media queries and the matchMedia and addEventListener javascript functions – so you wont need to include any other code to support responsive across all browsers.

Usage is really simple:


$('body').mediaQuery({
  w320: 'only screen and (min-width: 320px)',
  w480: 'only screen and (min-width: 480px) ',
  w768: 'only screen and (min-width: 768px)',
  w1024: 'only screen and (min-width: 1024px)'
});

This code will add the classes w320, w480, w768, w1024 to the body tag depending on each of the corresponding media queries matching.

Your css is then as simple as this eg:


.w320 .content p {
  background-color:#d45354;
}

.w480 .content p {
font-size:3em;
width:360px;
height:360px;
line-height:360px;
background-color:#818b85;
}

Checking for different media queries is now as simple as this line of jQuery code:


if ($(element).hasClass('w1024')) ...

You can view an example of the technique here: http://jameswestgate.github.com/mediaQuery/examples/

Extendify minimalist javascript framework released.

Extendify is a little library that could – it’s something I’ve worked on for a while and brings a few essentials to JavaScript that a seasoned programmer like me would miss in a language.

If you need namespacing, a simple class helper that works with the language, a script loader and a cool microtemplating feature all rolled into less than 2k, then consider heading over to the github page.

Ill talk about each feature in a subsequent post, but for now you can download the final release at https://github.com/jameswestgate/extendify

Let me know if you have any questions or suggestions!

An Intervention

We have been catering to the lowest common denominator of JavaScript versions for too long now. Why is it that we rush to polyfill an HTML5 or CSS3 feature, but doggedly stick with version 1.5 of JavaScript. Anyhoo, if you are sick of using for loops on arrays, miss the power of mapping functions on arrays or are forever patching the indexOf method I present a JavaScript 1.6 array polyfill. Enjoy.

Responsively adding webP images

Whilst working out an approach to selectively loading responsive images, I realised I had finally found a place for the webP format. A quick feature detect confirmed this would be possible. This post wraps everything up in the responsive images series by combining the feature detect with the responsive images code to provide a hearty complete solution to your responsive image needs.

If you view the page at http://opencomponents.com/flexible/ using the latest Opera or Chrome client, and inspect the images, you should notice that the image paths end in the .webp extension. This saves up to 50% download size on the larger images without any loss in quality.

On the smaller version of the images it was interesting to note that at default quality, the images were actually bigger. If I dropped the quality slightly, a more modest 20% gain was usually found. Must say though that the quality is still excellent.

Altering image sizes responsively in all browsers

If you view the responsive web page page by Ethan Marcott in IE8, you’ll notice that it doesn’t work in the same way as modern browsers. This is because IE8 and below doesn’t support media queries – the smart bit of css we use to conditionally style our page based on current or device width. We also need to evaluate media queries to set our img tag through javascript using windows.matchMedia and media query list addListener- this isn’t supported in IE9 or less.

We need another polyfill – to add media queries to IE8 and below and to add media query matching and listening in IE9 (as well as any other unsupported platforms). The responsive polyfill I’ve written combines elements of Scott Jehl’s respond.js polyfill for media queries, Paul Irish’s matchMedia.js polyfill and my own code for media query listeners whilst keeping performance a priority.

This allows us to use code to detect when to change the image or image size in the browser and set the correct image path on initial page load. We thus take the following steps:

- set up a media query to detect changes at a width of 600 pixels
– read the contents of noscript tags and add an image to the dom depending on the media query
– listen to the media query so that when it changes we can modify the image path accordingly.

var mql = window.matchMedia('only screen and (max-width: 600px)');
var elements;
	
//Get contents of noscript tags 
var tags = document.getElementsByTagName("noscript");

//Add image to dom depending on media query
for (var i=0, len=tags.length; i<len; i++) {
  var markup = tags[i].textContent.trim();

  if (mql.matches) markup = markup.replace("/large/", "/small/");
  tags[i].insertAdjacentHTML('afterend', markup);
}

//Scale up to large / down to small when media query changes
mql.addListener(function() {

  if (!elements) elements = document.getElementsByTagName("img");
		
  var from = (mql.matches) ? "/large/" : "/small/";
  var to = (mql.matches) ? "/small/" : "/large/";

  for (var i=0, len=elements.length; i<len; i++) {
    if (elements[i].className.indexOf("responsive") > -1)
      elements[i].src = elements[i].src.replace(from, to);
  }
});

View the example

Thoughts on this technique

It should be pointed out that strictly speaking, once we have the large image we dont need the small image - it is better just to scale it down. However I also think that the smaller image in a responsive design may often be different - perhaps a more cropped version - anyway this page exists to demonstrate the basic technique only.

We also dont use a jQuery style document.ready type approach - this is simply not needed for such a simple example - placing the code in the footer is more than sufficient. However - because the images are loaded fairly late in the day you can see the image 'waterfall' as they are loaded. A more advanced technique may only display them once they are fully loaded, perhaps with css such as

img.responsive {display:none}
noscript img.responsive {display:block}

Is it worth the extra script vs the reduced download? Probably. Certainly the noscript code is small. Making IE9 and below fully responsive may not be worth it however.

PS. The responsive script doesn't currently read style tags in the parent document - it could easily be modified to do so however.

Progressive enhancement of NOSCRIPT tags containing images

For the 2nd of our 4 part plan to solve the problem of responsive images using current browser standards, we need to put our noscript textContent polyfill to work. What better than to refactor the seminal responsive design original from A List Apart by Ethan Marcotte.

To start with, all we do is move the 6 character images into noscript tags, add our polyfill ot the bottom of the body and run a small amount of cross browser script to append the content of the noscript tag after itself. You can see the results here.


<script type="text/javascript" src="js/noscript.min.js"></script>
<script type="text/javascript">
var tags = document.getElementsByTagName("noscript");
for (var i=0, len=tags.length; i<len; i++) {
  var tag = tags[i];
  tag.insertAdjacentHTML('afterend', tag.textContent);
}
</script>


 
This provides us with the hook we need to dynamically modify image paths before they are added to the DOM.