jPrefetch jQuery plugin

I just released jPrefetch a nice little jQuery plugin that makes HTML5 prefetching a bit easier. You can very easily use it for your current solution (static website or even CMS), just by including it and adding data-prefetch="true" to the link that you want to prefetch. You can also pass a url (string) in order to start prefetching the provided url, in case you are loading a page that doesn’t have any link with the data-prefetch attribute. jPrefetch will take care all the rest, and start adding the necessary markup (metatags) in order to allow prefetching in supported browsers (tested in Chrome and Firefox). As you can see, the use of this is very easy and elegant. The plugin was mainly inspired by these two excellent articles, Mastering HTML5 Prefetching and Prefetching with HTML 5 and jQuery.

Feel free to fork it, use it, whatever 😉

Responsive web design and how to be nice to IE

Many people believe that Internet Explorer (especially 7 and 8) cannot render correctly responsive web sites. Well the truth is that IE sucks big time (especially versions previous to 9), although the above statement is partially true. With a tiny bit of effort you can make your responsive web site play nicely with IE as well. Let me tell you how.

The first thing you must do in any case (this tip is not only for responsive web design), is to make sure that IE is using the latest rendering engine it supports. We can do this very simply by including the below metatag. Finally, if the user has Google Frame (does anyone have it?) we tell IE to use that rendering engine.

See the Pen Responsive web design and how to be nice to IE by John Tsevdos (@tsevdos) on CodePen

Easy so far, the next major problem is that IE8 and below doesn’t recognise HTML5 elements. Again you can include either html5shiv or modernizr to fix this. Html5shiv is smaller in filesize and does the job but Modernizr can help you detect browser features (and not only that), the choice is yours.

Finally you can make IE understand media queries (a very important part of responsive web design) with the excellent Javascript polyfill Respond.js. That’s it, you’ve made it! With these very simple steps we can be nice to IE and make it treat right our responsive web sites.

The get() method is not working! Well try eq()…

Every now and then, I come across the very same issue, so I decided to write a post about it. Many new JS developers are struggling to find out why the below code is not working when applying jQuery’s get() method :

See the Pen The get() method is not working! Well try eq()… by John Tsevdos (@tsevdos) on CodePen

The selector is correct, and if we remove the get() method, it magically works!

The answer is pretty obvious if you check get()‘s documentation. The get() method returns a DOM object, not a jQuery one! This means that you don’t have access to jQuery’s fun methods… If you want a similar method (that returns a jQuery object) try eq(), it works the exact same way.

jQuery lights off effect

I’ve been working on a “lights off” effect for videos the other day. Here’s a demo page (with the appropriate code) that I might turn into a proper plugin if there is enough interest. Enjoy…

$(document).ready(function(){
	
		// Build the link
		$('.lightsoff').append('<div class="lightsoffbtn"><a href="#">Lights Off</a></div>');
		
		// Prepare the overlay
		$('body').append('<div class="lightsoff-ovelay off" style="position:relative; z-index:1; display:none;">close</div>');
		
		// Variables
		var $overlay = $('.lightsoff-ovelay'),
			$containers = $('.lightsoff'),
			$lightsoffTrigger = $('.lightsoffbtn a');
	
			
		// LightsOff events
		$lightsoffTrigger.each(function(){
		
			// Variables
			var $container = $(this).parent().parent();
	
			// Apply some CSS
			$container.css({ 'position': 'relative' });
	
			$(this).click(function(e){
	
				e.preventDefault();
					
				if ( $overlay.hasClass('off') ) {
	
					$container.css({
						'z-index': 4000
					});
	
					$overlay.css({
						'position': 'fixed',
						'display': 'block',
						'text-indent': -99999,
						'background-color' : '#000000',
						'width': '100%',
						'height': '100%',
						'top': 0,
						'left': 0,
						'z-index': 3000,
						'opacity': 0.7,
						'cursor': 'pointer'
					});
	
					$overlay.removeClass('off').addClass('on').fadeIn();
	
				} else if ( $overlay.hasClass('on') ) {
					e.preventDefault();
					$containers.css({ 'z-index': 0 });
					$overlay.removeClass('on').addClass('off').fadeOut();
				}
			
			});
		
		});
		
		$overlay.click(function(e){
			e.preventDefault();
			$containers.css({ 'z-index': 0 });
			$overlay.removeClass('on').addClass('off').fadeOut();
		});
	
	});Check out this Pen!

jQuery window.onload equivalent

Last week a reader contacted me noting that my equal heights script was not working. When I took a closer look at his code, I found out that the reason for it not working correctly wasn’t my script but the way jQuery works! The normal jQuery behaviour is to run the code when the DOM is ready and won’t wait for images/graphics etc, to load. There are some cases though, that someone needs to run a piece of code after the entire page is fully loaded. You can achieve that with the code bellow :

$(window).load(function() {
	// When the entire page is fully loaded
	$('#content, #sidebar').equalHeights();
});Check out this Pen!

The elements that needed equal heights contain images, so the script was miscalculating the max-height value because it wasn’t getting the correct height of the images (since they were still loading). The above code will fix that, since it will load the script when the entire window is fully loaded (including images).

Keep in mind that this is an event handler method (a shortcut for .bind('load', handler) ) and has nothing to do with the ajax load() method.

Organizing jQuery Code

Organizing jQuery code is not easy. Up to now, especially on small/medium scale projects, I used to have a huge jQuery ready function and place all my code there. Some times if I needed to run something on specific elements I was just doing a quick test to check if the element was on the document.

$(document).ready(function(){
	//jQuery code...
	if ( $('.someClass').length ) { // if element exists then run the below code
		// Do something
	}
});Check out this Pen!

The above technique is not too bad, it works just fine for a small or medium sized site, but what happens with a larger site that uses heavy javascript code? The answer came from a presentation I watched recently (Simple JavaScript & CSS Management With Rack by Mr. Avand Amiri – I strongly encourage you to watch it as well). The solution is really clean and pretty smart. Just create a javascript file (actually you can break it to as many files as you want) that will hold all your main objects. Below is a very basic “Greetings” object.

var Greetings = {
	alertFn: function () {
		alert('OK');
	},
 
	john: {
		sayHelloToJohn: function() {
			alert ('Hello John!');
		}
	}
// do something else, etc.
}Check out this Pen!

At the example above the object “Greetings” contains two methods (functions). As you can see, I could go further and create nested objects with their own methods. The idea is to organize my methods as well as I can.

Then I only have to call them into our usual jQuery ready function like this.

$(document).ready(function(){
  Greetings.alertFn();
});
// or
$(document).ready(function(){
	Greetings.john.sayHelloToJohn();
});Check out this Pen!

Keep in mind that this way I can follow any code structure/organization I need, so for example I can follow my application’s controllers structure and naming convention, or whatever makes more sense for my app. This way we get a simple, more robust, well-organised jQuery code, and not the classic document ready soup…

Wrap any amount of elements with jQuery

Update : Get the nwrapper plugin from the official jQuery plugins site.

jQuery provides a large variety of functions for element manipulation, that in most cases will manipulate the selected elements in no time. A very useful function for every day manipulation is the .wrap() function that we can use to wrap an HTML structure around each jQuery element. But what happens when we want to wrap an HTML structure on every n’th number of the selected elements? Unfortunately, jQuery doesn’t provide any options to the warp function in order to to do something similar.

After a bit of search I came across this solution for the jQuery forum, and created the below jQuery plug in.

(function($) {  
  
$.fn.nwrapper = function(options){  
  
    var defaults = {  
        wrapEvery      : 1,  
        defaultClasses : true,  
        extraClasses   : false,  
        htmlStructure  : 'div'  
    };  
  
    settings = $.extend({}, defaults, options);  
  
    var elements    = $(this).children();  
    var elementsLen = elements.length;  
  
    for ( var i = 0, numb = 1; i < elementsLen; i += settings.wrapEvery, numb++ ){  
  
        // Default Classes Array  
        var classes = [];  
        if ( settings.defaultClasses ) {  
  
            classes[0] = 'wrapper';  
            classes[1] = 'wrapper-' + numb;  
  
            if (numb==1) {  
                classes[2] = 'first';  
            }  
  
            if (numb==Math.ceil(elementsLen/settings.wrapEvery)) {  
                classes[2] = 'last';  
            }  
  
        }  
  
        // Merge Default class with Extra Class  
        if ( settings.extraClasses ) {  
            $.merge( classes, settings.extraClasses );  
        }  
  
        // If you find any classes crete the class string  
        if ( classes.length > 0 ) {  
            htmlClassesString = 'class="' + classes.join(" ") + '"';  
        } else {  
            htmlClassesString = '';  
        }  
  
        elements.filter(':eq(' + i + '), :lt(' + (i + settings.wrapEvery) + '):gt(' + i + ')').wrapAll('<' + settings.htmlStructure + ' ' + htmlClassesString + ' />');  
  
    }  
  
    return $(this);  
};  
  
})(jQuery);

$('#container').nwrapper({  
    wrapEvery      : 2,  
    //defaultClasses : true,  
    //extraClasses   : ['class1', 'class2'],  
    //htmlStructure  : 'span'  
});Check out this Pen!

To use it, select the parent element of the elements you want to wrap, choose how often you’ll apply the wrap (wrapEvery attribute – default is 1), choose if you need any default classes or even provide your own extra classes (extraClasses), and finally provide the HTML structured element you’ll use for a wrapper (the default is div, but you can also use a span).

Now you can wrap every n’th of your elements.

How to create a bookmarklet

A bookmarklet is a small Javascript program stored into a url. A user can bookmark the specific url, and execute the Javascript code on any page. The good news is that it’s not so hard to create one. A very simple example is the bookmarklet below:

<a href="javascript:alert("Phrappe.com rocks!")>A vary basic bookmarklet!</a>Check out this Pen!

As you can see, you instruct the browser to run a javascript url. You can drag & drop the link to your bookmarks, and execute the bookmarklet on any page! That’s the power of bookmarklets. Go on try it 😉

Unfortunately, we have some browser limitations on url size (usually 2000 characters), that makes it impossible to write serious js code straight into a url. To tackle this limitation we can use our bookmarklet as a loader to an external js file using the below code :

javascript:(function() {  
  var s=document.createElement("script");  
  s.src="http://phrappe.com/script.js";  
  document.body.appendChild(s);  
})();Check out this Pen!

We start with the standard js url notation, and then we create a self executing anonymous function. Into that function, we just create a new script element, pass a source attribute to it and append it to our current document. Then we can finally start writing some serious javascript code to our external script, without any of the usual bookmarklet limitations! The script itself can again be a self executing anonymous function (because we don’t want to mess with document’s js code and variables).

(function() {  
//code  
})();Check out this Pen!

Keep in mind that bookmarklets have access to all the content and code of the document within which we ran them. So if you don’t trust a boorkmarklet code, don’t use it on sensitive pages, because the bookmarklet can access sensitive and personal data such as cookies, variables or elements! Be extra careful when you use them and if you don’t trust the source/author don’t use them at all!

Below you can see a very simple bookmarklet I created to transform sites to a more console-like layout (black background, monospace green fonts, etc.).

Console it! (drag’n drop it to your bookmarks and try it at google.com 😉 ). You can see the code below or simply download it.

(function() { 

var body      = document.body,
	links     = document.getElementsByTagName('a');

body.setAttribute("style", "background-color:#000; color:#fff; font-family: \"Courier New\", Courier, monospace;");

for ( i in links ){
	links[i].setAttribute("style", "color:#347c17; font-family: \"Courier New\", Courier, monospace;");	
}

})();Check out this Pen!

Finally, a very useful bookmarklet I use all the time is jQuerify. It loads jQuery on any page. Then I can just do the cool stuff through console 😉

A really simple “equal heights” method for jQuery!

Nothing special, a really basic “equal heights” method written in jQuery.

$.fn.equalHeights = function() {  
    var maxHeight = 0;  
    $(this).each(function(index){  
        var height = $(this).height();  
  
        if (maxHeight < height) {  
            maxHeight = height  
        }  
   });  
   $(this).height(maxHeight);  
}

$("ul li").equalHeights();Check out this Pen!

Then you just need to apply the method on the element you want using $("ul li").equalHeights();.