Showing posts with label HTML element. Show all posts
Showing posts with label HTML element. Show all posts

Saturday, 24 December 2011

Creating a Simple Photo Album with jQuery Similar to Facebook

For the javascript part, I’ve decided to use jQuery as well as the jquery.cycle and jquery.lightbox plugins.


HTML structure


The HTML code needed for a gallery like this is actually rather simple. All we have to do, is to print the images as plain old linked HTML images and wrap image collections in container elements (DIVs).



<h1>My Photo Collection</h1>

<p id="intro">

  This is my photo album...yaddi-yaddi-ya...

</p>

<div class="album">

  <h2>Wicked Album</h2>

  <a href="photos/image1.jpg">

    <img src="photos/thumb_image1.jpg" alt="Lorem" />

  </a>

  <a href="photos/image2.jpg">

    <img src="photos/thumb_image2.jpg" alt="Ipsum" />

  </a>

  <a href="photos/image3.jpg">

    <img src="photos/thumb_image3.jpg" alt="Lorem" />

  </a>

</div>

<div class="album">

  <h2>Wickier Album</h2>

  <a href="photos/image4.jpg">

    <img src="photos/thumb_image4.jpg" alt="Ipsum" />

  </a>

  <a href="photos/image5.jpg">

    <img src="photos/thumb_image5.jpg" alt="Yadi" />

  </a>

  <a href="photos/image6.jpg">

    <img src="photos/thumb_image6.jpg" alt="Yadi" />

  </a>

  <a href="photos/image7.jpg">

    <img src="photos/thumb_image7.jpg" alt="Ya" />

  </a>

</div>

<div class="album">

  <h2>Wickiestest Album</h2>

  <a href="photos/image8.jpg">

    <img src="photos/thumb_image8.jpg" alt="Lorem" />

  </a>

  <a href="photos/image9.jpg">

    <img src="photos/thumb_image9.jpg" alt="Ipsum" />

  </a>

</div>




The Magic of jQuery Plug-Ins


In order to turn this into something a bit more exciting than a bunch of linked images with a blue border, we add some JavaScript and CSS to the page.

First, make sure to include jQuery, jQuery Cycle and jQuery Lightbox to the page. Then add the following JavaScript code to another .js-file that is loaded into the same page:



$(document).ready( function() {

  // Dynamically add nav buttons as these are not needed in non-JS browsers

  var prevNext = '<div id="album-nav"><button ' +

                   'class="prev">&laquo; Previous' +

                   '</button><button>' +

                   'Next &raquo;</button></div>';

  $(prevNext).insertAfter('.album:last');

  // Add a wrapper around all .albums and hook jquery.cycle onto this

  $('.album').wrapAll('<div id="photo-albums"></div>');

  $('#photo-albums').cycle({

    fx:     'turnDown',

    speed:  500,

    timeout: 0,

    next:   '.next',

    prev:   '.prev'

  });

  // Remove the intro on first click -- just for the fun of it

  $('.prev,.next').click(function () {

    $('#intro:visible').slideToggle();

  });

  // Add lightbox to images

  $('.album a').lightBox();

});




You may of course remove the cycling effect.
The only JavaScript you’d then need is $('.album a').lightBox();.

Adding Style Info


Last, we add some style info to make our albums look at least somewhat good.



/** for this example, I don't give a rats (*) about IE */

.album {

  width: 600px !important;

  clear: both;

}

.album h2 {

  clear: both;

}

.album a {

  display: block;

  float: left;

  margin-right: 1em;

  padding: 0.5em;

  border: 1px solid black;

  background-color: #eee;

  text-align: center;

}

.album a:hover {

  border-color: blue;

}

.album img {

  width: 72px;

  height: 100px;

  border: 0;

}

#album-nav {

  margin-top: 1em;

  max-width: 500px;

}

.prev, .next {

  border: 1px outset #ccc;

  color: #000075;

  background-color: white;

  font-weight:bold;

  padding: 0.25em;

}

.prev:hover,.next:hover {

  border-style: inset;

}

.prev {

  float: left;

}

.next {

  float: right;

}




Finish!

Friday, 23 December 2011

Lets see how facebook search is so fast

Some days before i came across a very well known website called facebook. And i was always wondering how can such a heavily loaded website be so seamlessly fast.

After a continuous google search, i found that they use AJAX and JQuery extensively with differnet caching technologies along with the following latest technologies.

1. Bigpipe
2. Comet (programming) or "Reverse Ajax"

I have implemented a simple reverse ajax in my website fb.walletchange.com/profile.php @ the search portion. You can mark a remarkable change in search time after implementing the same.

The trick goes like this


a) Load a static page first

b) Pull the data as soon as the page loads using ajax into a hidden div

c) Use jQuery to organise the data for perfect user interactivity

 

    

 

a) Lets create our page layout div first


<DIV id=main>
<H1>Facebook type instant search engine - super speed
</H1>
Filter friends list : <INPUT id=filter>
<DIV id=container>
<DIV>
<UL>
<?php
while($row=mysql_fetch_array($sql_res))
{
$username=$row['username'];

?>
<LI>
<DIV>
<DIV><?=$username?></DIV></DIV></LI>
<?php
}

?>
</UL></DIV></DIV></DIV>


b) We will proceed now by adding jQuery and instant search script and some style attributes to the page


<SCRIPT src="jquery.js"></SCRIPT>

<SCRIPT src="instant-search.js"></SCRIPT>

<STYLE>BODY {
FONT-WEIGHT: 300; FONT-SIZE: 16px; MARGIN: 0px 10%; COLOR: #333; FONT-STYLE: normal; FONT-FAMILY: 'Helvetica Neue', Helvetica, Arial, sans-serif
}
.name SPAN {
BACKGROUND: #fbffc6
}
UL {
PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px
}
UL LI {
BORDER-RIGHT: #ddd 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #ddd 1px solid; PADDING-LEFT: 5px; FONT-SIZE: 20px; BACKGROUND: #eee; FLOAT: left; PADDING-BOTTOM: 5px; MARGIN: 3px; BORDER-LEFT: #ddd 1px solid; WIDTH: 150px; LINE-HEIGHT: 70px; PADDING-TOP: 5px; BORDER-BOTTOM: #ddd 1px solid; LIST-STYLE-TYPE: none; HEIGHT: 70px; TEXT-ALIGN: center
}
#container {
BORDER-RIGHT: #b9b9b9 1px solid; BORDER-TOP: #b9b9b9 1px solid; MARGIN-TOP: 20px; BORDER-LEFT: #b9b9b9 1px solid; WIDTH: 100%; BORDER-BOTTOM: #b9b9b9 1px solid; HEIGHT: 440px; webkit-box-shadow: 0 0 15px #aaa; moz-box-shadow: 0 0 15px #aaa; box-shadow: 0 0 15px #aaa
}
#container .content {
OVERFLOW: auto; HEIGHT: 440px
}
#main {
MARGIN: 0px auto; WIDTH: 100%;
}
INPUT {
BORDER-RIGHT: #ddd 1px solid; BORDER-TOP: #ddd 1px solid; FONT-SIZE: 20px; BORDER-LEFT: #ddd 1px solid; BORDER-BOTTOM: #ddd 1px solid
}
A {
COLOR: #31499c; TEXT-DECORATION: none
}
H1 {
FONT-WEIGHT: normal; TEXT-ALIGN: center
}
</STYLE>

Thursday, 15 December 2011

Google plus like drag and drop adding groups


You might have marked a cool feature in google plus, where we add people to groups simply by dragging it to the perticular frame.

Here is a explanation of the above implementation using JQuery and PHP.
Google Plus Style Drag and Drop adding Groups


Sample database contains three tables and relationship between Members and Groups.

Members
Table contains members(users) data such as member_id, member_image and etc.
CREATE TABLE IF NOT EXISTS `members` ( `member_id` int(9) NOT NULL AUTO_INCREMENT, `member_name` varchar(220) NOT NULL, `member_image` text NOT NULL, `dated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`member_id`) );

Groups
Contains groups information.
CREATE TABLE IF NOT EXISTS `groups` ( `group_id` int(9)  AUTO_INCREMENT, `group_name` varchar(220), `sort` int(9), `date` timestamp  DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`group_id`), KEY `sort` (`sort`) );

User_group
Members and Groups table relationship table contains user_id(same as memeber_id), group_id, member_id() and sort(ordering)
CREATE TABLE IF NOT EXISTS `user_group` ( `id` int(9) NOT NULL AUTO_INCREMENT, `user_id` int(9) NOT NULL, `group_id` int(9) NOT NULL, `member_id` int(9) NOT NULL, `sort` int(9) NOT NULL, PRIMARY KEY (`id`) );

Javascript
Here draggable applying for two classes .members and .group
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.js"></script> <script type="text/javascript" src="jquery.livequery.min.js"></script> <script type="text/javascript" > $(function() { // Initiate draggable for public and groups var $gallery = $( ".members, .group" ); $( "img", $gallery ).live("mouseenter", function() { var $this = $(this); if(!$this.is(':data(draggable)')) { $this.draggable({ helper: "clone", containment: $( "#demo-frame" ).length ? "#demo-frame" : "document", cursor: "move" }); } }); // Initiate Droppable for groups // Adding members into groups // Removing members from groups // Shift members one group to another $(".group").livequery(function(){ var casePublic = false; $(this).droppable({ activeClass: "ui-state-highlight", drop: function( event, ui ) { var m_id = $(ui.draggable).attr('rel'); if(!m_id) { casePublic = true; var m_id = $(ui.draggable).attr("id"); m_id = parseInt(m_id.substring(3)); } var g_id = $(this).attr('id'); dropPublic(m_id, g_id, casePublic); $("#mem"+m_id).hide(); $( "<li></li>" ).html( ui.draggable ).appendTo( this ); }, out: function(event, ui) { var m_id = $(ui.draggable).attr('rel'); var g_id = $(this).attr('id'); $(ui.draggable).hide("explode", 1000); removeMember(g_id,m_id); } }); }); // Add or shift members from groups function dropPublic(m_id, g_id,caseFrom) { $.ajax({ type:"GET", url:"groups.php?m_id="+m_id+"&g_id="+g_id, cache:false, success:function(response){ $.get("groups.php?reload_groups", function(data){ $("#groupsall").html(data); $("#added"+g_id).animate({"opacity" : "10" },10); $("#added"+g_id).show(); $("#added"+g_id).animate({"margin-top": "-50px"}, 450); $("#added"+g_id).animate({"margin-top": "0px","opacity" : "0" }, 450); }); } }); } // Remove memebers from groups // It will restore into public groups or non grouped members function removeMember(g_id,m_id) { $.ajax({ type:"GET", url:"groups.php?do=drop&mid="+m_id, cache:false, success:function(response){ $("#removed"+g_id).animate({"opacity" : "10" },10); $("#removed"+g_id).show(); $("#removed"+g_id).animate({"margin-top": "-50px"}, 450); $("#removed"+g_id).animate({"margin-top": "0px","opacity" : "0" }, 450); $.get("groups.php?reload", function(data){ $("#public").html(data); }); } }); } }); </script>

groups.php
<?php require_once("multipleDiv.inc.php"); // Initiate Object $obj = new Multiplediv(); // Add or Update Ajax Call if(isset($_GET['m_id']) and isset($_GET['g_id'])) { $obj->addMembers((int)$_GET['m_id'], (int)$_GET['g_id']); exit; } // Remove Memebers from groups Ajax call if(isset($_GET['do'])) { $obj->removeMember($_GET['mid']); exit; } // Reload groups each ajax call if(isset($_GET['reload'])){ echo $obj->getMembers_reload(); exit; } if(isset($_GET['reload_groups'])){ echo $obj->getmembergroups_reload(); exit; } // Initiate Groups and members $members = $obj->public_members(); $groups = $obj->groups(); ?> Friends <div id="main_portion"> <div id="public"> <!-- Initiate members --> <?php if(!isset($members)) $members = $obj->public_members(); if($members) { foreach($members as $member) { extract($member); echo "<div class='members' id='mem".$member_id."'>\n"; echo "<img src='images/".$member_image."' rel='".$member_id."'>\n"; echo "<b>".ucwords($member_name)."</b>\n"; echo "</div>"; } } else echo "Members not available"; ?> </div> <div id="groupsall"> Groups <!-- Initiate Groups --> <?php if(!isset($groups)) $groups = $obj->groups(); if($groups) { foreach($groups as $group) { extract($group); echo "<div id='".$group_id."' class='group'>\n"; echo ucwords($group_name); echo "<div id='added".$group_id."' class='add' style='display:none;' ><img src='images/green.jpg'></div>"; echo "<div id='removed".$group_id."' class='remove' style='display:none;' ><img src='images/red.jpg'></div>"; echo "<ul>\n"; echo $obj->updateGroups($group_id); echo "</ul></div>"; } } ?>


multipleDiv.inc.php
Download this and modify database connection credentials.
<?php // Database declaration's define("SERVER", "localhost"); define("USER", "username"); define("PASSWORD", "password"); define("DB", "database");class Multiplediv { ........................ ........................ ......................... } ?>

Saturday, 3 December 2011

Pagination with Jquery, PHP , Ajax and MySQL.

Friends, In my current employment i need to develop huge database driven web application. Which normally deals with millions  of records. I use indexing and cache techniques. Along with that i use jquery to make it handy for end use.

   

Database
MySQL messages table contains two columns msg_id and message
CREATE TABLE messages
(
msg_id INT PRIMARY KEY AUTO_INCREMENT,
message VARCHAR(150)
);

JavaScript Code
This script works like a data controller.
<script type="text/javascript" src="http://ajax.googleapis.com/
ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
{function loading_show()
{
$('#loading').html("<img src='images/loading.gif'/>").fadeIn('fast');
}function loading_hide()
{
$('#loading').fadeOut();
}

function loadData(page)
{
loading_show();
$.ajax
({
type: "POST",
url: "load_data.php",
data: "page="+page,
success: function(msg)
{
$("#container").ajaxComplete(function(event, request, settings)
{
loading_hide();
$("#container").html(msg);
});
}
});
}
loadData(1); // For first time page load default results
$('#container .pagination li.active').live('click',function(){
var page = $(this).attr('p');
loadData(page);
});
});

</script>


load_data.php
Contains PHP coding. Displaying data from the messages table.
<?php
if($_POST['page'])
{
$page = $_POST['page'];
$cur_page = $page;
$page -= 1;
$per_page = 15; // Per page records
$previous_btn = true;
$next_btn = true;
$first_btn = true;
$last_btn = true;
$start = $page * $per_page;
include"db.php";
$query_pag_data = "SELECT msg_id,
message from messages LIMIT $start, $per_page";
$result_pag_data = mysql_query($query_pag_data)
or die('MySql Error' . mysql_error());
$msg = "";
while ($row = mysql_fetch_array($result_pag_data))
{
$htmlmsg=htmlentities($row['message']); //HTML entries filter
$msg .= "<li><b>" . $row['msg_id'] . "</b> " . $htmlmsg . "</li>";
}
$msg = "<div class='data'><ul>" . $msg . "</ul></div>"; // Content for Data
/* -----Total count--- */
$query_pag_num = "SELECT COUNT(*) AS count FROM messages"; // Total records
$result_pag_num = mysql_query($query_pag_num);
$row = mysql_fetch_array($result_pag_num);
$count = $row['count'];
$no_of_paginations = ceil($count / $per_page);
/* -----Calculating the starting and endign values for the loop----- *///Some Code. Available in download script }
?>


Enhanced by Zemanta

Tuesday, 29 November 2011

Facebook Style Alert Confirm Box with jQuery and CSS

                 

Create a facebook style alert box with jquery plug-in jquery.alert.js. Bellow is the complete tutorial

HTML / Javascript Code
Contains javascript and HTML Code.



<link href="facebook.alert.css" rel="stylesheet" type="text/css">

<script type="text/javascript"

src="http://ajax.googleapis.com/ajax/ libs/jquery/1.3.0/jquery.min.js"></script>

<script type="text/javascript" src="jquery.alert.js"></script>

<script type="text/javascript"> $(document).ready( function()

{ $("#delete_confirm").click( function()

{ jConfirm('Are you sure you want ot delete this thread?', '', function(r)

{ if(r==true) { $("#box").fadeOut(300); } }); }); });

</script>
<div id="box" style=" background-color:#ffffcc;">

<a href="#" id="delete_confirm">Delete</a>

</div>



facebook.alert.css
Contains CSS code.



#popup_container

{

font-family:'Lucida Grande',arial;

font-weight:bold;

text-align:left;

font-size: 12px;

width: 364px;

height: 86px;

background: #F3F3F3;

border:solid 1px #dedede;

border-bottom: solid 2px #456FA5;

color: #000000; }
#popup_title

{ display:none; }
#popup_message

{ padding-top: 15px; padding-left: 15px; }
#popup_panel

{ text-align: left; padding-left:15px; }
input

{

background-color:#476EA7;

padding:3px; color:#FFFFFF;

margin-top:20px;

margin-right:10px;

}


Saturday, 26 November 2011

Facebook Style Footer Admin Panel

                 

The popularity of social media has been booming in the past few years and Facebook definitely has climbed high to the top of the social network rankings. Facebook has many Ajax driven features and applications that are very impressive, and one of the things I particularly like is the footer admin panel, where it neatly organizes frequently used links and applications.

This week I would like to cover part 1 of how to recreate the Facebook footer admin panel with CSS and jQuery.


Step 1. Wireframe and Tooltip Bubbles – HTML & CSS


Lay out the wireframe of the admin panel using an unordered list for the foundation. The last two list items (Alert Panel & Chat Panel) will have sub-panels nested within them. Since these two panels will float to the right, the order in the markup will be reversed.

Tooltip foundation

Notice that there is a <small> tag nested within the <a> tag, this is how we will achieve our tooltip bubble on the navigation.

HTML


<div id="footpanel">
<ul id="mainpanel">
<li><a href="#">Inspiration <small>
Design Bombs</small></a></li>
<li><a href="#">View Profile <small>
View Profile</small></a></li>
<li><a href="#">Edit Profile <small>
Edit Profile</small></a></li>
<li><a href="#">Contacts <small>
Contacts</small></a></li>
<li><a href="#">Messages (10) <small>
Messages</small></a></li>
<li><a href="#">Play List <small>
Play List</small></a></li>
<li><a href="#">Videos <small>
Videos</small></a></li>
<li id="alertpanel"><a href="#">
Alerts</a></li>
<li id="chatpanel"><a href="#">
Friends (<strong>18</strong>)</a></li>
</ul>
</div>

CSS


First start by fixing the panel to the bottom of the viewport.
#footpanel {
position: fixed;
bottom: 0; left: 0;
z-index: 9999;
/*--Keeps the panel on top of all other elements--*/
background: #e3e2e2;
border: 1px solid #c3c3c3;
border-bottom: none;
width: 94%;
margin: 0 3%;
}

As you may already know, IE6 does not understand fixed positioning. I stumbled across a tutorial that fixed this problem*.
*html #footpanel { /*--IE6 Hack - Fixed Positioning to the Bottom--*/
margin-top: -1px;
/*--Prevents IE6 from having an infinity scroll bar - due to 1px border on #footpanel--*/
position: absolute;
top:expression(eval(
document.compatMode &&document.compatMode=='CSS1Compat')
?documentElement.scrollTop+(
documentElement.clientHeight-this.clientHeight)
: document.body.scrollTop +(
document.body.clientHeight-this.clientHeight));
}

*Note: Due to heavy loading on the browser, an alternative solution would be to either use an position: absolute; or if the situation/client allows it use display: none; for those with IE6.

Style the unordered list which will be the foundation of this panel.
#footpanel ul {
padding: 0; margin: 0;
float: left;
width: 100%;
list-style: none;
border-top: 1px solid #fff;
/*--Gives the bevel feel on the panel--*/
font-size: 1.1em;
}
#footpanel ul li{
padding: 0; margin: 0;
float: left;
position: relative;
}
#footpanel ul li a{
padding: 5px;
float: left;
text-indent: -9999px;
/*--For text replacement - Shove text off of the page--*/
height: 16px; width: 16px;
text-decoration: none;
color: #333;
position: relative;
}
html #footpanel ul li a:hover{ background-color: #fff; }
html #footpanel ul li a.active {
/*--Active state when sub-panel is open--*/
background-color: #fff;
height: 17px;
margin-top: -2px;
/*--Push it up 2px to attach the active button to sub-panel--*/
border: 1px solid #555;
border-top: none;
z-index: 200;
/*--Keeps the active link on top of the sub-panel--*/
position: relative;
}

Tooltip Demo

Declare the text replacement for each link.
You can download these great icons by Pinvoke here.
#footpanel a.home{
background: url(home.png) no-repeat 15px center;
width: 50px;
padding-left: 40px;
border-right: 1px solid #bbb;
text-indent: 0;
/*--Reset text indent since there will be a
combination of both text and image--*/
}
a.profile{ background: url(user.png)
no-repeat center center; }
a.editprofile{ background: url(wrench_screwdriver.png)
no-repeat center center; }
a.contacts{ background: url(address_book.png)
no-repeat center center; }
a.messages{ background: url(mail.png)
no-repeat center center; }
a.playlist{ background: url(document_music_playlist.png)
no-repeat center center; }
a.videos{ background: url(film.png)
no-repeat center center; }
a.alerts{ background: url(newspaper.png)
no-repeat center center; }
#footpanel a.chat{
background: url(balloon.png)
no-repeat 15px center;
width: 126px;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
padding-left: 40px;
text-indent: 0;
/*--Reset text indent since there will be
a combination of both text and image--*/
}
#footpanel li#chatpanel, #footpanel li#alertpanel {
 float: right; }
/*--Right align the chat and alert panels--*/

Tooltip Demo

Style the tooltip bubble, by default the <small> tag will be hidden with a display:none;. On hover over, allow the tooltip to appear with a display:block;
#footpanel a small {
text-align: center;
width: 70px;
background: url(pop_arrow.gif) no-repeat center bottom;
padding: 5px 5px 11px;
display: none; /*--Hide by default--*/
color: #fff;
font-size: 1em;
text-indent: 0;
}
#footpanel a:hover small{
display: block; /*--Show on hover--*/
position: absolute;
top: -35px;
/*--Position tooltip 35px above the list item--*/
left: 50%;
margin-left: -40px; /*--Center the tooltip--*/
z-index: 9999;
}

Friday, 25 November 2011

Getting started

To use jQuery, you need to include it on the pages where you wish to take advantage of it. You can do this by downloading jQuery from their website at www.jquery.com. There is usually a choice between a "Production" version and a "Development" version. The first is for your live website, because it has been minified and compressed to take up the least amount of space, which is important for your visitors, whose browser will have to download the jQuery file along with the rest of your website. For testing and development, the "Development" version is best. It hasn't been minified or compressed, so when you run into an error, you can actually see where in jQuery it happens.

Once downloaded, you will have to reference the jQuery JavaScript file on your pages, using the <script> HTML tag. The easiest way is to place the downloaded jquery.js file in the same directory as the page from where you wish to use it and then reference it like this, in the section of your document:

<script type="text/javascript" src="jquery-1.5.1.js"></script>

A part of your page should now look something like this:

<head>
        <title>jQuery test</title>
        <script type="text/javascript" src="jquery-1.5.1.js"></script>
</head>

A more modern approach, instead of downloading and hosting jQuery yourself, is to include it from a CDN (Content Delivery Network). Both Google and Microsoft host several different versions of jQuery and other JavaScript frameworks. It saves you from having to download and store the jQuery framework, but it has a much bigger advantage: Because the file comes from a common URL that other websites may use as well, chances are that when people reaches your website and their browser requests the jQuery framework, it may already be in the cache, because another website is using the exact same version and file. Besides that, most CDN's will make sure that once a user requests a file from it, it's served from the server closest to them, so your European users won't have to get the file all the way from the US and so on.

You can use jQuery from a CDN just like you would do with the downloaded version, only the URL changes. For instance, to include jQuery 1.5.1 from Google, you would write the following:

<script type="text/javascript" 
src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>

I suggest that you use this approach, unless you have a specific reason for hosting jQuery yourself. Here is a link to the jQuery CDN information from Google:

http://code.google.com/intl/da/apis/libraries/devguide.html#jquery

Or if you prefer to use it from Microsoft:

http://www.asp.net/ajaxlibrary/cdn.ashx#jQuery_Releases_on_the_CDN_0

Read on to learn how to start using jQuery.

Hello, world!

Every decent programming tutorial will start with a "Hello, world!" example and this tutorial is yet another one of them. In the previous chapter, we learned how to include jQuery on our page, so that we may start using all of its great features. You need to know a bit more about how jQuery works, before you can start writing your own code, but just to make sure that everything is working, and for you to see how simple jQuery is, let's kick off with a little example:

<div id="divTest1"></div>
<script type="text/javascript">
$("#divTest1").text("Hello, world!");
</script>

Okay, so we have a div tag with the id of "divTest1". In the JavaScript code we use the $ shortcut to access jQuery, then we select all elements with an id of "divTest1" (there is just one though) and set its text to "Hello, world!". You may not know enough about jQuery to understand why and how this works, but as you progress through this tutorial, all of the elements will be explained in detail.

Even such a simple task as this one would actually require quite a few extra keystrokes if you had to do it in plain JavaScript, with no help from jQuery:

<div id="divTest2"></div>
<script type="text/javascript">
document.getElementById("divTest2").innerHTML = "Hello, world!";
</script>

And it would be even longer if our HTML element didn't have an ID, but for instance just a class.

Normally though, you wait for the document to enter the READY state before you start manipulating its content. The above examples will work in most browsers and likely even work when you do more advanced stuff, but certain tasks may fail if you try to do them before the document is loaded and ready. Fortunately, jQuery makes this very easy as well, as we will see in the next chapter. After that, we will start looking into one of the most important aspects of jQuery, which has already been used in the above example: Selectors.

Method chaining

Yet another one of the really cool aspects of jQuery is the fact that most of the methods returns a jQuery object that you can then use to call another method. This allows you to do command chaining, where you can perform multiple methods on the same set of elements, which is really neat because it saves you and the browser from having to find the same elements more than once. Here's an example, and don't worry about the jQuery methods used in the following examples - they will be explained in later chapters:

<div id="divTest1"></div>
<script type="text/javascript">
        $("#divTest1").text("Hello, world!").css("color", "blue");
</script>

It works like this: We instantiate a new jQuery object and select the divTest1 element with the $ character, which is a shortcut for the jQuery class. In return, we get a jQuery object, allowing us to manipulate the selected element. We use that object to call the text() method, which sets the text of the selected element(s). This method returns the jQuery object again, allowing us to use another method call directly on the return value, which is the css() method.

We can add more method calls if needed, but at some point, the line of code will become quite long. Fortunately for us, JavaScript is not very strict when it comes to the syntax, so you can actually format it like you want, including linebreaks and indentations. For instance, this will work just fine as well:

<div id="divTest2"></div>
<script type="text/javascript">
        $("#divTest2").text("Hello, world!")
                                        .removeClass("blue")
                                        .addClass("bold")
                                        .css("color", "blue");                                  
</script>

JavaScript will simply throw away the extra whitespace when interpreting the code and execute it as one long line of code with several method calls.

Note that some methods doesn't return the jQuery object, while others only return it depending on the parameters you pass to it. A good example of that is the text() method used above. If no parameters are passed to it, the current text of the selected element(s) is returned instead of a jQuery object, while a single parameter causes jQuery to set the specified text and return a jQuery object.

Introduction to jQuery selectors

A very common task when using JavaScript is to read and modify the content of the page. To do this, you need to find the element(s) that you wish to change, and this is where selector support in jQuery will help you out. With normal JavaScript, finding elements can be extremely cumbersome, unless you need to find a single element which has a value specified in the ID attribute. jQuery can help you find elements based on their ID, classes, types, attributes, values of attributes and much, much more. It's based on CSS selectors and as you will see after going through this tutorial, it is extremely powerful.

Because this is such a common task, the jQuery constructor comes in several forms that takes a selector query as an argument, allowing you to locate element(s) with a very limited amount of code for optimal efficiency. You can instantiate the jQuery object simply by writing jQuery() or even shorter using the jQuery shortcut name: $(). Therefore, selecting a set of elements is as simple as this:

$(<query here>)

With the jQuery object returned, you can then start using and altering the element(s) you have matched. In the following chapters, you will see examples of some of the many ways you can select elements with jQuery.

Using elements, ID's and classes

The #id selector


A very common selector type is the ID based, which we saw in the "Hello, world" example. It uses the ID attribute of a HTML tag to locate the desired element. An ID should be unique, so you should only use this selector when you wish to locate a single, unique element. To locate an element with a specific ID, write a hash character, followed by the ID of the element you wish to locate, like this:
$("#divTest")

An example of it in use:

<div id="divTest"></div>
<script type="text/javascript">
$(function()
{
        $("#divTest").text("Test");
});
</script>

Now, while there is only a single element that matches our query above, you should be aware that the result is a list, meaning that it can contain more than one element, if the query matches more than one. A common example of this is to match all elements which uses one or several CSS classes.

The .class selector


Elements with a specific class can be matched by writing a . character followed by the name of the class. Here is an example:

<ul>
        <li class="bold">Test 1</li>
        <li>Test 2</li>
        <li class="bold">Test 3</li>
</ul>
<script type="text/javascript">
$(function()
{
        $(".bold").css("font-weight", "bold");
});
</script>

The element selector


You can also match elements based on their tag names. For instance, you can match all links on a page like this:

$("a")

Or all div tags like this:

$("div")

If you use a multi-element selector, like the class selector we used in the previous example, and we know that we're looking for elements of a specific type, it's good practice to specify the element type before the selector. Not only is it more precise, it's also faster for jQuery to process, resulting in more responsive sites. Here is a re-written version of the previous example, where we use this method:
$("span.bold").css("font-weight", "bold");

This will match all span elements with "bold" as the class. Of course, it can be used with ID's and pretty much all of the other selectors as well.

Selectors can do much more for you though. Read on for more cool examples.

Using attributes

In the previous chapter, we saw how we could find elements in a page from their class or their ID. These two properties are related because of the fact that you can use them to style the elements with CSS, but with jQuery, you can actually find elements based on any kind of attribute. It comes with a bunch of attribute selector types and in this article, we will look into some of them.

Find elements with a specific attribute


The most basic task when selecting elements based on attributes is to find all the elements which has a specific attribute. Be aware that the next example doesn't require the attribute to have a specific value, in fact, it doesn't even require it to have a value. The syntax for this selector is a set of square brackets with the name of the desired attribute inside it, for instance [name] or [href]. Here is an example:

<span title="Title 1">Test 1</span><br />
<span>Test 2</span><br />
<span title="Title 3">Test 3</span><br />

<script type="text/javascript">
$(function()
{
        $("[title]").css("text-decoration", "underline");
});
</script>

We use the attribute selector to find all elements on the page which has a title attribute and then underline it. As mentioned, this will match elements with a title element no matter what their value is, but sometimes you will want to find elements with a specific attribute which has a specific value.

Find elements with a specific value for a specific attribute


Here's an example where we find elements with a specific value:

<a href="http://www.google.com" target="_blank">Link 1</a><br />
<a href="http://www.google.com" target="_self">Link 2</a><br />
<a href="http://www.google.com" target="_blank">Link 3</a><br />

<script type="text/javascript">
$(function()
{
        $("a[target='_blank']").append(" [new window]");
});
</script>

The selector simply tells jQuery to find all links (the a elements) which has a target attribute that equals the string value "_blank" and then append the text "[new window]" to them. But what if you're looking for all elements which don't have the value? Inverting the selector is very easy:
$("a[target!='_blank']").append(" [same window]");

The difference is the != instead of =, a common way of negating an operator within many programming languages.

And there's even more possibilities:

Find elements with a value which starts with a specific string using the ^= operator:
$("input[name^='txt']").css("color", "blue");

Find elements with a value which ends with a specific string using the $= operator:
$("input[name$='letter']").css("color", "red");

Find elements with a value which contains a specific word:
$("input[name*='txt']").css("color", "blue");

Getting and setting attributes [attr()]

In the previous chapter, we saw how easy it was to get and set text and HTML content from and to an element. Fortunately, changing one or more attributes of an element is just as easy. We use the attr() method for this, which in its simplest form takes one parameter: The name of the attribute we wish to get:

<a href="http://www.google.com" id="aGoogle1">Google Link</a>
<script type="text/javascript">
$(function()
{
        alert($("#aGoogle1").attr("href"));
});
</script>

In this example, we get the value of the "href" attribute of our link and then show it to the user. To change an attribute, we simply specify an extra parameter:

<a href="http://www.google.com" id="aGoogle2">Google Link</a>
<script type="text/javascript">
$(function()
{
        $("#aGoogle2").attr("href", "http://www.google.co.uk");
});
</script>

This will change the link to point to the British version of Google. The attr() method can also take a map of name/value pairs, for setting multiple attributes at the same time. Here we set both the href and the title attributes simultaneously:

<a href="http://www.google.com" id="aGoogle3">Google Link</a>
<script type="text/javascript">
$(function()
{
        $("#aGoogle3").attr(
        {
                "href" : "http://www.google.co.uk",
                "title" : "Google.co.uk"
        });
});
</script>

The attr() method also supports the special overload where the value parameter is instead a callback function, allowing you to access the index of the element selected as well as the existing attribute value. Here's an example of just that:

<a href="http://www.google.com/" class="google">Google.com</a><br />
<a href="http://www.google.co.uk/" class="google">Google UK</a><br />
<a href="http://www.google.de/" class="google">Google DE</a><br />

<script type="text/javascript">
$(function()
{
        $("a.google").attr("href", function(index, oldValue)
        {
                return oldValue + "imghp?tab=wi";
        });
});
</script>

We simply change all the Google links to point to the Image search instead of the default page, by adding an extra parameter to the href attribute. In this example we don't really use the index parameter, but we could have if we needed it, to tell us which index in the list of elements selected we're currently dealing with.

Getting and setting CSS classes

Just like it's very easy to manipulate content and attributes of elements, as we saw in the previous chapters, it's equally easy to manipulate the CSS of elements. jQuery gives you easy access to changing both the style attribute, which you manipulate using the css() method, as well as the class(es) of an element, where several different methods lets you modify it.

Let's start by looking into changing the class attribute. The class attribute takes one or several class names, which may or may not refer to a CSS class defined in your stylesheet. Usually it does, but you may from time to time add class names to your elements simply to be able to reach them easily from jQuery, since jQuery has excellent support for selecting elements based on their class name(s).

I have defined a couple of very simple CSS selectors in my stylesheet, mostly for testing purposes:
.bold {
        font-weight: bold;
}

.blue {
        color: blue;
}

In the following example we will use three of the most interesting class related methods: hasClass(), which checks if one or several elements already has a specific class defined, addClass(), which simply adds a class name to one or several elements and the removeClass() methods, which will.... well, you've probably already guessed it.

<a href="javascript:void(0);" onclick="ToggleClass(this);">Toggle class</a>

<script type="text/javascript">
function ToggleClass(sender)
{

        if($(sender).hasClass("bold"))
                $(sender).removeClass("bold");
        else
                $(sender).addClass("bold");
}
</script>

The example is actually very simple. When the link is clicked, we send the link itself (this) as a parameter to the ToggleClass() method that we have defined. In it, we check if the sender already has the "bold" class - if it has, we remove it, otherwise we add it. This is a pretty common thing to do, so obviously the jQuery people didn't want us to write an entire three lines of code to it. That's why they implemented the toggleClass() method, with which we can turn our entire example above into a single line of code:

<a href="javascript:void(0);" onclick="$(this).toggleClass('bold');">
Toggle class</a>

Of course, we can select multiple elements, where we can add or remove multiple classes, as well. Here's an example of just that:

<div id="divTestArea1">
        <span>Test 1</span><br />
        <div>Test 2</div>
        <b>Test 3</b><br />
</div>
<script type="text/javascript">
$(function()
{
        $("#divTestArea1 span, #divTestArea1 b").addClass("blue");
        $("#divTestArea1 div").addClass("bold blue");
});
</script>

First we select the span and the b tag, which we add a single class to: the bold class. Then we select the div tag, which we add two classes to, separated by a space: The bold and the blue class. The removeClass() methods works just the same way, allowing you to specify several classes to be removed, separated with a space.

The before() and after() methods

In the previous chapter, we used the append() and prepend() methods to insert stuff inside an element, but in some cases, you need to insert things before or after one or several elements instead. jQuery has the before() and after() methods for just this purpose, and they are just as easy to use. Check out this example:

<a href="javascript:void(0);" onclick="$('input.test1')
.before('<i>Before</i>');">Before</a>  
<a href="javascript:void(0);" onclick="$('input.test1')
.after('<b>After</b>');">After</a>

<br /><br />

<input type="text" class="test1" value="Input 1" name="txtInput1" /><br />
<input type="text" class="test1" value="Input 2" name="txtInput2" /><br />

Depending on which of the two links you click, an italic or a bold tag will be inserted before or after each input element on the page using the "test1" class. Just like with append() and prepend(), both after() and before() allows you to use HTML strings, DOM elements and jQuery objects as parameters and an infinite amount of them as well. We'll demonstrate that in the next example:

<a href="javascript:void(0);" onclick="InsertElements();">Insert elements</a>
<br /><br />
<span id="spnTest2">Hello world? </span>

<script type="text/javascript">
function InsertElements()
{
        var element1 = $("<b></b>").text("Hello ");
        var element2 = "<i>there </i>";
        var element3 = document.createElement("u");
        element3.innerHTML = "jQuery!";

        $("#spnTest2").after(element1, element2, element3);
}
</script>

In this example, we create a jQuery object, an HTML string and a JavaScript DOM element, and then we use the after() method to insert all of them after our span tag. Of course, the before() method could have been used in exactly the same way.

There are variations of the before() and after() methods, called insertBefore() and insertAfter(). They do pretty much the same, but they do it the other way around, so instead of calling them on the elements you wish to insert data before or after, with a parameter of what is to be inserted, you do the exact opposite. Which method to use obviously depends on the situation, but here's an example showing you how to use them both:

<a href="javascript:void(0);" onclick="InsertElementsBefore();">
Insert elemenets</a>
<br /><br />
<span id="spnTest3">Hello world? </span>

<script type="text/javascript">
function InsertElementsBefore()
{      
        $("#spnTest3").before($("<i></i>").text("before() "));
        $("<b></b>").text("insertBefore() ").insertBefore("#spnTest3");
}
</script>

In this example, we insert the items before the span tag, but you could of course do the exact same using after() and insertAfter(), if you wish to insert after the target elemenet. As you can see, the result is the same - only the order of what we do differs.

Introduction to events

Events in JavaScript are usually something where you write a snippet of code or a name of a function within one of the event attributes on an HTML tag. For instance, you can create an event for a link by writing code like this:

<a href="javascript:void(0);" onclick="alert('Hello, world!');">Test</a>

And of course this is still perfectly valid when using jQuery. However, using jQuery, you can bind code to the event of an element even easier, especially in cases where you want to attach anonymous functions or use the same code for multiple events, or even the same code for multiple events of multiple elements. As an example, you could bind the same event to all links and span tags in your document, with only a few lines of code like this:
<script type="text/javascript">
$(function()
{
        $("a, span").bind("click", function() {
                alert('Hello, world!');
        });
});
</script>

We use the bind method, which is essential when working with events and jQuery. In the following chapters we will tell you more about how it works, along with other event related information you need.

Tuesday, 30 August 2011

Facebook Style CSS JQuery drop down menus



Now a days drop down menus are becoming more and more popular. They arebeing used in  most modern websites like facebook, gmail, gplus, orkut, gmail, yahoo...

There is no secret that they are using JQuery and HTML to implement the above feature.

Even you can do this by writing some very simple code.

 

       

 

 

 

 

Step-1:

Lets write our HTML code.
<div style="height:300px;">
            <div style="width:162px;">
                <dl style="">
                   <dt>
                   <a class="" id="linkglobal"
                   style="cursor: pointer;"></a></dt>
                    <dd>
                        <ul style="display: none;" id="ulglobal">
                            <li><a href="#">Everyone</a></li>
                            <li><a href="#">Friends</a></li>
                            <li><a href="#">Only Me</a></li>
                            <li><a href="#">Customize</a></li>
                      </ul>
                   </dd>
                </dl>
            </div>
        </div>

Step-2:
The next step is to add some CSS which will further stylize the menu
which is going to look just like facebook.
<style type="text/css">

    *{
        padding:0;
        margin:0;
    }

    body{
        color: #333333;
        direction: ltr;
        font-family:
        "lucida grande",tahoma,verdana,arial,sans-serif;
        font-size: 11px;
        text-align: left;
    }

/* Grey Small Dropdown */

/* General dropdown styles */
.dropdown dl{ margin-left:5px; }
.dropdown dd, .dropdown dt, .dropdown ul
{ margin:0px; padding:0px; }
.dropdown dd { position:relative; }

/* DT styles for sliding doors */
.dropdown dt a {background:#EEEEEE
url(privacyOff.png) no-repeat scroll right center;
    display:block; width:40px; height:22px; cursor:pointer;}

.dropdown dt a.selected{
    background:#EEEEEE url(privacyOn.png)
    no-repeat scroll right center;
}
.dropdown dt a span {
cursor:pointer; display:block; padding:5px;}

/* UL styles */
.dropdown dd ul {
background:#EEEEEE none repeat scroll 0 0; display:none;
    list-style:none; padding:3px 0; position:absolute;
    left:0px; width:160px; left:auto; right:0;
    border:1px solid #656565; cursor:pointer;
    }
.dropdown dd ul li{
background-color:#EEEEEE; margin:0; width:160px;
}
.dropdown span.value { display:none;}
.dropdown dd ul li a {
display:block; font-weight:normal; width:137px;
text-align:left; overflow:hidden; padding:2px 4px 3px 19px;
color:#111111; text-decoration:none;
}
.dropdown dd ul li a:hover{
background:#656565; color:white; text-decoration:none;
}
.dropdown dd ul li a:visited{
text-decoration:none;
}
</style>

Step-3 :

Now lets include the JQuery into our webpage and start writing the necessary JQuery function calls.
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".dropdown dt a").click(function() {

// Change the behaviour of onclick states for links within the menu.
var toggleId = "#" + this.id.replace(/^link/,"ul");

// Hides all other menus depending on JQuery id assigned to them
$(".dropdown dd ul").not(toggleId).hide();

//Only toggles the menu we want since the menu could be showing and we want to hide it.
$(toggleId).toggle();

//Change the css class on the menu header to show the selected class.
if($(toggleId).css("display") == "none"){
$(this).removeClass("selected");
}else{
$(this).addClass("selected");
}

});

$(".dropdown dd ul li a").click(function() {

// This is the default behaviour for all links within the menus
var text = $(this).html();
$(".dropdown dt a span").html(text);
$(".dropdown dd ul").hide();
});

$(document).bind('click', function(e) {

// Lets hide the menu when the page is clicked anywhere but the menu.
var $clicked = $(e.target);
if (! $clicked.parents().hasClass("dropdown")){
$(".dropdown dd ul").hide();
$(".dropdown dt a").removeClass("selected");
}});
});
</script>

Saturday, 7 May 2011

Gmail, Facebook Style jQuery Chat amazing!!!



Demo
Please load the following links in different browsers otherwise it wont work:

[caption id="" align="alignright" width="245" caption="Image via CrunchBase"]Image representing Facebook as depicted in Cru...[/caption]

Sample Chat User Swadesh
Sample Chat User Vimla
Sample Chat User Brijesh

Introduction
Everyone loves the gmail and facebook inline chat modules. This jQuery chat module enables you to seamlessly integrate Gmail/Facebook style chat into your existing website.



Features
1. Gmail style bottom right display of chat boxes
2. Keeps chat boxes open and stores state (data) even when pages are browsed/refreshed similar to Facebook
3. Displays “Sent at…” after 3 minutes of inactivity
4. Displays “X says…” & blinks chat boxes when window is not in focus
5. Minimize and close chat boxes
6. Auto-resize of text input box
7. Auto-scrolling of chat text
8. Auto-back-off polling policy (hits the server less-often when chat activity is low)
9. Extremely simple to integrate into existing site

Getting Started
First download the module (link below)

You must first create a mySQL table as below (or import db.txt provided in project files)
CREATE TABLE IF NOT EXISTS `chat` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `from` varchar(255) NOT NULL DEFAULT '',
  `to` varchar(255) NOT NULL DEFAULT '',
  `message` text NOT NULL,
  `sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `recd` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=539 ;


CREATE TABLE IF NOT EXISTS `users` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) DEFAULT NULL,
  `password` varchar(30) DEFAULT NULL,
  `email` varchar(100) DEFAULT NULL,
  `gender` varchar(8) NOT NULL,
  `dob` varchar(16) NOT NULL,
  `phone` varchar(20) NOT NULL,
  `profile_image` varchar(50) NOT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=21 ;

--
-- Dumping data for table `users`
--

INSERT INTO `users` (`uid`, `username`, `password`, `email`, `gender`, `dob`, `phone`, `profile_image`) VALUES
(1, 'Swadesh', 'pass1', 'itswadesh@gmail.com', '', '', '', ''),
(2, 'Brijesh', 'pass1', 'brijesh@gmail.com', '', '', '', ''),
(3, 'Vimla', '', 'pass1', 'vimla@gmail.com', '', '', '');

Add the following scripts to your page template
<code><script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/chat.js"></script>
</code>

Add the following CSS to your page
<link type="text/css" rel="stylesheet" media="all" href="css/chat.css" />
<link type="text/css" rel="stylesheet" media="all" href="css/screen.css" /><!--[if lte IE 7]>
<link type="text/css" rel="stylesheet" media="all" href="css/screen_ie.css" />
<![endif]-->

Now in your list of users online, add “javascript:chatWith(’USERNAME’);” function where USERNAME is the username for that particular user who he/she wants to chat with.

Once that is done, edit chat.php and set your database parameters and try your website.

For better understanding, load 3 different browsers (internet explorer, firefox, safari) and point them to samplea.php, sampleb.php and samplec.php.

Click on “chat with john doe” link and watch the chat functionality come alive!

Inorder to integrate your existing website, you must place all your content between the “main_container” div tag.

Browser Compatibility
1. Firefox 2+
2. Internet Explorer 6+
3. Safari 2+
4. Opera 9+

Friday, 6 May 2011

Create A Vertical Scrolling News Ticker With jQuery and jCarousel Lite

                                


News Ticker is a fantastic way to present headlines or minor updates to your readers. The smooth scrolling effect will attract your readers and generate more clicks to your site.

There are a lot of great tutorials discussing on how to implement news ticker, however most of the tutorials that i found are not really suitable for a beginner. So, i decided to use jQuery and its plugin jCarousel Lite to create a simple yet powerful news ticker.

Why i choose jCarousel Lite? it is because jCarousel Lite is a tiny but powerful plugin. Furthermore, you can easily tweak/configure it to achieve different effects. News ticker is just a sample application for this plugin.

Let’s start to create our news ticker using jCarousel Lite. Download both jQuery and jCarousel Lite before we can start.

news-ticker

Step 1


Let’s create a blank index.htm file, and include jQuery and jCarousel Lite. Also, create a blank style.css file for later use.
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
<script src="jquery-latest.pack.js" type="text/javascript"></script>
<script src="jcarousellite_1.0.1c4.js" type="text/javascript"></script>
</head>
</html>

Step 2


In the same document, create a <div> and name it as “newsticker-demo”. Basically, this is the container for the news ticker. We will have another <div> class name “newsticker-jcarousellite”. Remember, this is very important and you will need to use the same class name when you configure jCarousel Lite.

Step 3


In the “newsticker-jcarousellite” <div>, create an <ul> element. Each news will be an individual <li> element. In this example, i had created 6 news, so i will have 6 <li> elements(but i am not going to show all). We will have the thumbnail float to the left, while the title and other information float to the right.
<li>
<div>
<a href="#"><img src="images/1.jpg"></a>
</div>
<div>
<a href="http://www.vladstudio.com/wallpaper/?knight_lady">
The Knight and the Lady</a>
<span>Category: Illustrations</span>
</div>
<div></div>
</li>

Step 4


After you created your <li> element, it is the time for us to configure the jCarousel. Under the <head>, add these scripts:
<script type="text/javascript">
$(function() {
$(".newsticker-jcarousellite").jCarouselLite({
vertical: true,
visible: 3,
auto:500,
speed:1000
});
});
</script>

The script itself is pretty straight forward. The “auto:500″ means it will auto-scroll every 500ms. There are a lot of options which you can configure easily. Refer the documentation for more information.

Step 5


Basically you had done everything, except styling your content. So, just copy and paste the scripts below in your style.css file.
* { margin:0; padding:0; }

#newsticker-demo {
width:310px;
background:#EAF4F5;
padding:5px 5px 0;
font-family:Verdana,Arial,Sans-Serif;
font-size:12px;
margin:20px auto;
}

#newsticker-demo a { text-decoration:none; }
#newsticker-demo img { border: 2px solid #FFFFFF; }

#newsticker-demo .title {
text-align:center;
font-size:14px;
font-weight:bold;
padding:5px;
}

.newsticker-jcarousellite { width:300px; }
.newsticker-jcarousellite ul li{ list-style:none; display:block; padding-bottom:1px; margin-bottom:5px; }
.newsticker-jcarousellite .thumbnail { float:left; width:110px; }
.newsticker-jcarousellite .info { float:right; width:190px; }
.newsticker-jcarousellite .info span.cat { display: block; font-size:10px; color:#808080; }.clear { clear: both; }

Finish!


Enhanced by Zemanta

Thursday, 5 May 2011

Web Site Optimization: 13 Simple Steps

I've came across some websites like Facebook, gmail and Yahoo and always wonder "how these are so fast!!!!!!"

I searched some websites and blogs related to this and hand picked some of the following techniques which really worked for my new social N/W website.

The tutorial is divided into four parts:

  1. basic optimization rules

  2. optimizing assets (images, scripts, and styles)

  3. optimizations specific to scripts

  4. optimizations specific to styles


Credits and Suggested Reading

The article is not going to explain Yahoo!’s performance rules in detail, so you’d do well to read through them on your own for a better understanding of their importance, the reasoning behind the rules, and how they came to be. Here’s the list of rules in question:

  1. Make fewer HTTP requests

  2. Use a Content Delivery Network

  3. Add an Expires header

  4. Gzip components

  5. Put CSS at the top

  6. Move scripts to the bottom

  7. Avoid CSS expressions

  8. Make JavaScript and CSS external

  9. Reduce DNS lookups

  10. Minify JavaScript

  11. Avoid redirects

  12. Remove duplicate scripts

  13. Configure ETags


// <![CDATA[
/*<![CDATA[*/// */
// ]]>

You can read about these rules on the Yahoo! Developer Network site. You can also check out the book “High Performance Web Sites” by Steve Souders, and the performance research articles on the YUI blog by Tenni Theurer.
Basic Optimization Rules

Decrease Download Sizes

Decreasing download sizes isn’t even in Yahoo!’s list of rules — probably because it’s so obvious. However I don’t think it hurts to reiterate the point — let’s call it Rule #0.

When we look at a simple web page we see:

  • some HTML code

  • different page components (assets) referenced by the HTML


The assets are images, scripts, styles, and perhaps some external media such as Flash movies or Java applets (remember those?). So, when it comes to download sizes, you should aim to have all the assets as lightweight as possible — advice which also extends to the page’s HTML content. Creating lean HTML code often means using better (semantic) markup, which also overlaps with the SEO (search engine optimization) efforts that are a necessary part of the site creation process. As most professional web developers know, a key characteristic of good markup is that it only describes the content, not the presentation of the page (no layout tables!). Any layout or presentational elements should be moved to CSS.

Here’s an example of a good approach to HTML markup for a navigation menu:

<ul id="menu"> <li><a href="home.html">Home</a></li> <li><a href="about.html">About</a></li> <li><a href="contact.html">Contact</a></li> </ul>

This sort of markup should provide “hooks” to allow for the effective use of CSS and make the menu look however you want it to — whether that means adding fancy bullets, borders, or rollovers, or placing the menu items into a horizontal menu. The markup is minimal, which means there are fewer bytes to download; it’s semantic, meaning it describes the content (a navigation menu is a list of links); and finally, being minimal, it also gives you an SEO advantage: it’s generally agreed that search engines prefer a higher content-to-markup ratio in the pages that they index.

Once you’re sure your markup is lightweight and semantic, you should go through your assets and make sure they are also of minimal size. For example, check whether it’s possible to compress images more without losing too much quality, or to choose a different file format that gives you better compression. Tools such as PNGOUT and pngcrush are a good place to start.

Make Fewer HTTP Requests

Making fewer HTTP requests turns out to be the most important optimization technique, with the biggest impact. If your time is limited, and you can only complete one optimization task, pick this one. HTTP requests are generally the most “expensive” activity that the browser performs while displaying your page. Therefore, you should ensure that your page makes as few requests as possible.

How you can go about that, while maintaining the richness of your pages?

  • Combine scripts and style sheets: Do you have a few <a title="Look up the tag in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/script"><script> tags in your head? Well, merge the .js files into one and save your visitors some round trips; then do the same with the CSS files.

  • Use image sprites: This technique allows you to combine several images into one and use CSS to show only the part of the image that’s needed. When you combine five or ten images into a single file, already you’re making a huge saving in the request/response overhead.

  • Avoid redirects: a redirect adds another client-server round trip, so instead of processing your page immediately after receiving the initial response, the browser will have to make another request and wait for the second response.

  • Avoid frames: if you use frames, the browser has to request at least three HTML pages, instead of just one — those of the frameset as well as each of the frames.


You’ve got the basics now. In summary, make your page and its assets smaller in size, and use fewer assets by combining them wherever you can. If you concentrate on this aspect of optimization only, you and your visitors will notice a significant improvement.

Now let’s explore some of the Yahoo! recommendations in more detail, and see what other optimizations can be made to improve performance.
Optimizing Assets

Use a Content Delivery Network

A Content Delivery Network (CDN) is a network of servers in different geographical locations. Each server has a copy of a site’s files. When a visitor to your site requests a file, the file is delivered from the nearest server (or the one that’s experiencing the lightest load at the time).

This setup can have a significant impact on your page’s overall performance, but unfortunately, using a CDN can be pricey. As such, it’s probably not something you’d do for a personal blog, but it may be useful when a client asks you to build a site that’s likely to experience high volumes of traffic. Some of the most widely known CDN providers are Akamai and Amazon, through its S3 service.

There are some non-profit CDNs in the market; check the CDN Wikipedia article to see if your project might qualify to use one of them. For example, one free non-profit peer-to-peer CDN is Coral CDN, which is extremely easy to integrate with your site. For this CDN, you take a URL and append “nyud.net” to the hostname. Here’s an example:

http://example.org/logo.png

becomes:

http://example.org.nyud.net/logo.png

Host Assets on Different Domains but Reduce DNS Lookups

After your visitor’s browser has downloaded the HTML for a page and figured out that a number of components are also needed, it begins downloading those components. Browsers restrict the number of simultaneous downloads that can take place; as per the HTTP/1.1 specification, the limit is two assets per domain.

Because this restriction exists on a per-domain basis, you can use several domains (or simply use subdomains) to host your assets, thus increasing the number of parallel downloads. Most shared hosts will allow you to create subdomains. Even if your host places a limit on the number of subdomains you can create (some restrict you to a maximum of five), it’s not that important, as you won’t need to utilize too many subdomains to see some noticeable performance improvements.

However, as Rule #9 states, you should also reduce the number of DNS lookups, because these can also be expensive. For every domain or subdomain that hosts a page asset, the browser will need to make a DNS lookup. So the more domains you have, the more your site will be slowed down by DNS lookups. Yahoo!’s research suggests that two to four domains is an optimal number, but you can decide for yourself what’s best for your site.

As a general guideline, I’d suggest you use one domain to host HTML pages and two other domains for your assets. Here’s an example:

  • www.sitepoint.com – hosts only HTML (and maybe content images)

  • i1.sitepoint.com – hosts JS, CSS, and some images

  • i2.sitepoint.com – hosts most of the site’s images


Different hosting providers will probably offer different interfaces for creating subdomains, and ideally they should provide you with an option to specify the directory that holds the files for the subdomain. For example, if your canonical domain is www.sitepoint.com, and it points to /home/sitepoint/htdocs, ideally you should be able to create the subdomain i1.sitepoint.com (either via an administration control panel or by creating a symbolic link in the file system) and point it to the same folder, /home/sitepoint/htdocs. This way, you can keep all files in the same location, just as they are in your development environment, but reference them using a subdomain.

However, some hosts may prevent you from creating subdomains, or may restrict your ability to point to particular locations on the file system. In such cases, your only real options is to physically copy the assets to the new location. Don’t be tempted to create some kind of redirect in this case — it will only make things worse, as it creates two requests for each image.

If your hosting provider doesn’t allow subdomains at all, you always have the option of buying more domains and using them purely to host assets — after all, that’s what a lot of big sites do. Yahoo! uses the domain yimg.com, Amazon has images-amazon.com, and SitePoint has sitepointstatic.com. If you own several sites, or manage the hosting of your client’s sites, you might consider buying two domains, such as yourdomain-i1.com and yourdomain-i2.com, and using them to host the components for all the sites you maintain.

Place Assets on a Cookie-free Domain

If you set a lot of cookies, the request headers for your pages will increase in size, since those cookies are sent with each request. Additionally, your assets probably don’t use the cookies, so all of this information could be repeatedly sent to the client for no reason. Sometimes, those headers may even be bigger than the size of the asset requested — these are extreme cases of course, but it happens. Consider downloading those small icons or smilies that are less than half a kB, and requesting them with 1kB worth of HTTP headers.

If you use subdomains to host your assets, you need to make sure that the cookies you set are for your canonical domain name (e.g. www.example.org) and not for the top-level domain name (e.g. example.org). This way, your asset subdomains will be cookie-free. If you’re attempting to improve the performance of an existing site, and you’ve already set your cookies on the top-level domain, you could consider the option of hosting assets on new domains, rather than subdomains.

Split the Assets Among Domains

It’s completely up to you which assets you decide to host on i1.example.org and which you decide to host on i2.example.org — there’s no clear directive on this point. Just make sure you don’t randomize the domain on each request, as this will cause the same assets to be downloaded twice — once from i1 and once from i2.

You could aim to split your assets evenly by file size, or by some other criterion that makes sense for your pages. You may also choose to put all content images (those that are included in your HTML with <img /> tags) on i1 and all layout images (those referenced by CSS’s background-image:url()) on i2, although in some cases this solution may not be optimal. In such cases, the browser will download and process the CSS files and then, depending on which rules need to be applied, will selectively download only images that are needed by the style sheet. The result is that the images referenced by CSS may not download immediately, so the load on your asset servers may not be balanced.

The best way to decide on splitting assets is by experimentation; you can use Firebug‘s Net panel to monitor the sequence in which assets download, then decide how you should spread components across domains in order to speed up the download process.
// <![CDATA[
/*<![CDATA[*/// */
// ]]>

Configure DNS Lookups on Forums and Blogs

Since you should aim to have no more than four DNS lookups per page, it may be tricky to integrate third-party content such as Flickr images or ads that are hosted on a third-party server. Also, hotlinking images (by placing on your page an <img /> tag whose src attribute points to a file on another person’s server) not only steals bandwidth from the other site, but also harms your own page’s performance, causing an extra DNS lookup.

If your site contains user-generated content (as do forums, for example), you can’t easily prevent multiple DNS lookups, since users could potentially post images located anywhere on the Web. You could write a script that copies each image from a user’s post to your server, but that approach can get fairly complicated.

Aim for the low-hanging fruit. For example, in the phpBB forum software, you can configure whether users need to hotlink their avatar images or upload them to your server. In this case, uploaded avatars will result in better performance for your site.

Use the Expires Header

For best performance, your static assets should be exactly that: static. This means that there should be no dynamically generated scripts or styles, or <a title="Look up the tag in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/img"><img> tags pointing to scripts that generate dynamic images. If you had such a need — for example, you wanted to generate a graphic containing your visitor’s username — the dynamic generation could be taken “offline” and the result cached as a static image. In this example, you could generate the image once, when the member signs up. You could then store the image on the file system, and write the path to the image in your database. An alternative approach might involve scheduling an automated process (a cron job, in UNIX) that generates dynamic components and saves them as static files.

Having assets that are entirely static allows you to set the Expires header for those files to a date that is far in the future, so that when an asset is downloaded once, it’s cached by the browser and never requested again (or at least not for a very long time, as we’ll see in a moment).

Setting the Expires header in Apache is easy: add an .htaccess file that contains the following directives to the root folder of your i1 and i2 subdomains:

ExpiresActive On ExpiresDefault "modification plus 10 years"

The first of these directives enables the generation of the Expires header. The second sets the expiration date to 10 years after the file’s modification date, which translates to 10 years after you copied the file to the server. You could also use the setting “access plus 10 years”, which will expire the file 10 years after the user requests the file for the first time.

If you want, you can even set an expiration date per file type:

ExpiresActive On ExpiresByType application/x-javascript "modification plus 2 years" ExpiresByType text/css "modification plus 5 years"

For more information, check the Apache documentation on mod_expires.

Name Assets

The problem with the technique that we just looked at (setting the Expires header to a date that’s far into the future) occurs when you want to modify an asset on that page, such as an image. If you just upload the changed image to your web server, new visitors will receive the updated image, but repeat visitors won’t. They’ll see the old cached version, since you’ve already instructed their browser never to ask for this image again.

The solution is to modify the asset’s name — but it comes with some maintenance hurdles. For example, if you have a few CSS definitions pointing to img.png, and you modify the image and rename it to img2.png, you’ll have to locate all the points in your style sheets at which the file has been referenced, and update those as well. For bigger projects, you might consider writing a tool to do this for you automatically.

You’ll need to come up with a naming convention to use when naming your assets. For example, you might:

  • Append an epoch timestamp to the file name, e.g. img_1185403733.png.

  • Use the version number from your source control system (cvs or svn for example), e.g. img_1.1.png.

  • Manually increment a number in the file name (e.g. when you see a file named img1.png, simply save the modified image as img2.png).


There’s no one right answer here — your decision will be depend on your personal preference, the specifics of your pages, the size of the project and your team, and so on.

If you use CVS, here’s a little PHP function that can help you extract the version from a file stored in CVS:

function getVersion($file) { $cmd = 'cvs log -h %s'; $cmd = sprintf($cmd, $file); exec($cmd, $res); $version = trim(str_replace('head: ', '', $res[3])); return $version; } // example use $file = 'img.png'; $new_file = 'img_' . getVersion($file) . '.png';

Serve gzipped Content

Most modern browsers understand gzipped (compressed) content, so a well-performing page should aim to serve all of its content compressed. Since most images, swf files and other media files are already compressed, you don’t need to worry about compressing them.

You do, however, need to take care of serving compressed HTML, CSS, client-side scripts, and any other type of text content. If you make XMLHttpRequests to services that return XML (or JSON, or plain text), make sure your server gzips this content as well.

If you open the Net panel in Firebug (or use LiveHTTPHeaders or some other packet sniffer), you can verify that the content is compressed by looking for a Content-Encoding header in the response, as shown in the following example:

Example request:

GET /2.2.2/build/utilities/utilities.js HTTP/1.1 Host: yui.yahooapis.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.5) Gecko/20070713 Firefox/2.0.0.5 Accept-Encoding: gzip,deflate

Example response:

HTTP/1.x 200 OK Last-Modified: Wed, 18 Apr 2007 17:36:33 GMT Vary: Accept-Encoding Content-Type: application/x-javascript Content-Encoding: gzip Cache-Control: max-age=306470616 Expires: Sun, 16 Apr 2017 00:01:52 GMT Date: Mon, 30 Jul 2007 21:18:16 GMT Content-Length: 22657 Connection: keep-alive

In this request, the browser informed the server that it understands gzip and deflate encodings (Accept-Encoding: gzip,deflate) and the server responded with gzip-encoded content (Content-Encoding: gzip).

There’s one gotcha when it comes to serving gzipped content: you must make sure that proxies do not get in your way. If an ISP’s proxy caches your gzipped content and serves it to all of its customers, chances are that someone with a browser that doesn’t support compression will receive your compressed content.

To avoid this you can use the Vary: Accept-Encoding response header to tell the proxy to cache this response only for clients that send the same Accept-Encoding request header. In the example above, the browser said it supports gzip and deflate, and the server responded with some extra information for any proxy between the server and client, saying that gzip-encoded content is okay for any client that sends the same Accept-Encoding content.

There is one additional problem here: some browsers (IE 5.5, IE 6 SP 1, for instance) claim they support gzip, but can actually experience problems reading it (as described on the Microsoft downloads site, and the support site). If you care about people using these browsers (they usually account for less than 1% of a site’s visitors) you can use a different header — Cache-Control: Private — which eliminates proxy caching completely. Another way to prevent proxy caching is to use the header Vary: *.

To gzip or to Deflate?

If you’re confused by the two Accept-Encoding values that browsers send, think of deflate as being just another method for encoding content that’s less popular among browsers. It’s also less efficient, so gzip is preferred.

Make Sure you Send gzipped Content

Okay, now let’s see what you can do to start serving gzipped content in accordance with what your host allows.

Option 1: mod_gzip for Apache Versions Earlier than 2

If you’re using Apache 1.2 and 1.3, the mod_gzip module is available. To verify the Apache version, you can check Firebug’s Net panel and look for the Server response header of any request. If you can’t see it, check you provider’s documentation or create a simple PHP script to echo this information to the browser, like so:

<?php echo apache_get_version(); ?>

In the Server header signature, you might also be able to see the mod_gzip version, if it’s installed. It might look like something like this:

Server: Apache/1.3.37 (Unix) mod_gzip/1.3.26.1a.....

Okay, so we’ve established that we want to compress all text content, PHP script output, static HTML pages, JavaScripts and style sheets before sending them to the browser. To implement this with mod_gzip, create in the root directory of your site an .htaccess file that includes the following:

mod_gzip_on Yes mod_gzip_item_include mime ^application/x-javascript$ mod_gzip_item_include mime ^application/json$ mod_gzip_item_include mime ^text/.*$ mod_gzip_item_include file \.html$ mod_gzip_item_include file \.php$ mod_gzip_item_include file \.js$ mod_gzip_item_include file \.css$ mod_gzip_item_include file \.txt$ mod_gzip_item_include file \.xml$ mod_gzip_item_include file \.json$ Header append Vary Accept-Encoding

The first line enables mod_gzip. The next three lines set compression based on MIME-type. The next section does the same thing, but on the basis of file extension. The last line sets the Vary header to include the Accept-Encoding value.

If you want to send the Vary: * header, use:

Header set Vary *

Note that some hosting providers will not allow you to use the Header directive. If this is the case, hopefully you should be able to substitute the last line with this one:

mod_gzip_send_vary On

This will also set the Vary header to Accept-Encoding.

Be aware that there might be a minimum size condition on gzip, so if your files are too small (less than 1kb, for example), they might not be gzipped even though you’ve configured everything correctly. If this problem occurs, your host has decided that the gzipping process overhead is unnecessary for very small files.

Option 2: mod_deflate for Apache 2.0

If your host runs Apache 2 you can use mod_deflate. Despite its name, mod_deflate also uses gzip compression. To configure mod_deflate, add the following directives to your .htaccess file:

AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-javascript application/json Header append Vary Accept-Encoding
// <![CDATA[
/*<![CDATA[*/// */
// ]]>

Option 3: php.ini

Ideally we’d like Apache to handle the gzipping of content, but unfortunately some hosting providers might not allow it. If your hosting provider is one of these, it might allow you to use custom php.ini files. If you place a php.ini file in a directory, it overwrites PHP configuration settings for this directory and its subdirectories.

If you can’t use Apache’s mod_gzip or mod_deflate modules, you might still be able to compress your content using PHP. In order for this solution to work, you’ll have to configure your web server so that all static HTML, JavaScript and CSS files are processed by PHP. This means more overhead for the server, but depending on your host, it might be your only option.

Add the following directives in your .htaccess file:

AddHandler application/x-httpd-php .css AddHandler application/x-httpd-php .html AddHandler application/x-httpd-php .js

This will ensure that PHP will process these (otherwise static) files. If it doesn’t work, you can try renaming the files to have a .php extension (like example.js.php, and so on) to achieve the same result.

Now create a php.ini file in the same directory with the following content:

[PHP] zlib.output_compression = On zlib.output_compression_level = 6 auto_prepend_file = "pre.php" short_open_tag = 0

This enables compression and sets the compression level to 6. Values for the compression level range from 0 to 9, where 9 is the best (and slowest) compression. The last line sets up a file called pre.php to be executed at the beginning of every script, as if you had typed <?php include "pre.php"; ?> at the top of every script. You’ll need this file in order to set Content-Type headers, because some browsers might not like it when you send a CSS file that has, for example, a text/html content type header.

The short_open_tag setting is there to disable PHP short tags (<? ... ?>, as compared to <?php ... ?>). This is important because PHP will attempt to treat the <?xml tag in your HTML as PHP code.

Finally, create the file pre.php with the following content:

<?php $path = pathinfo($_SERVER['SCRIPT_NAME']); if ($path['extension'] == 'css')  { header('Content-type: text/css'); } if ($path['extension'] == 'js')  { header('Content-type: application/x-javascript'); } ?>

This script will be executed before every file that has a .php, .html, .js or .css file extension. For HTML and PHP files, the default Content-Type text/html is okay, but for JavaScript and CSS files, we change it using PHP’s header function.

Option 3 (Variant 2): PHP Settings in .htaccess

If your host allows you to set PHP settings in your .htaccess file, then you no longer need to use php.ini file to configure your compression settings. Instead, set the PHP setting in .htaccess using php_value (and php_flag).

Looking at the modified example from above, we would have the same pre.php file, no php.ini file, and a modified .htaccess that contained the following directives:

AddHandler application/x-httpd-php .css AddHandler application/x-httpd-php .html AddHandler application/x-httpd-php .js php_flag zlib.output_compression on php_value zlib.output_compression_level 6 php_value auto_prepend_file "pre.php" php_flag short_open_tag off

Option 4: In-script Compression

If your hosting provider doesn’t allow you to use php_value in your .htaccess file, nor do they allow you to use a custom php.ini file, your last resort is to modify the scripts to manually include the common pre.php file that will take care of the compression. This is the least-preferred option, but sometimes you may have no other alternative.

If this is your only option, you’ll either be using an .htaccess file that contains the directives outlined in Option 3 above, or you’ll have had to rename every .js and .css file (and .xml, .html, etc.) to have a .php extension. At the top of every file, add <?php include "pre.php"; ?> and create a file called pre.php that contains the following content:

<?php ob_start("ob_gzhandler"); $path = pathinfo($_SERVER['SCRIPT_NAME']); if ($path['extension'] == 'css')  { header('Content-type: text/css'); } if ($path['extension'] == 'js')  { header('Content-type: application/x-javascript'); } ?>

As I indicated, this is the least favorable option of all — you should try Option 1 or 2 first, and if they don’t work, consider Option 3 or 4, or a combination of both, depending on what your host allows.

Once you’ve established the degree of freedom your host permits, you can use the technique that you’ve employed to compress your static files to implement all of your Apache-related settings. For example, earlier I showed you how to set the Expires header. Well, guess what? Some hosts won’t allow it. If you find yourself in this situation, you can use PHP’s header function to set the Expires header from your PHP script.

To do so, you might add to your pre.php file something like this:

<?php header("Expires: Mon, 25 Dec 2017 05:00:00 GMT"); ?>

Disable ETags

Compared to the potential hassles that can be encountered when implementing the rule above, the application of this rule is very easy. You just need to add the following to your .htaccess file:

FileETags none

Note that this rule applies to sites that are in a server farm. If you’re using a shared host, you could skip this step, but I recommend that you do it regardless because:

  • Hosts change their machines for internal purposes.

  • You may change hosts.

  • It’s so simple.


Use CSS Sprites

Using a technique known as CSS sprites, you can combine several images into a single image, then use the CSS background-position property to show only the image you need. The technique is not intended for use with content images (those that appear in the HTML in <img /> tags, such as photos in a photo gallery), but is intended for use with ornamental and decorative images. These images will not affect the fundamental usability of the page, and are usually referenced from a style sheet in order to keep the HTML lean (Rule #0).

Let’s look at an example. We’ll take two images. The first is help.png; the second is rss.png. From these, we’ll create a third image, sprite.png, which contains both images.

Combining two image files into a single image

The resulting image is often smaller in size than the sum of the two files’ sizes, because the overhead associated with an image file is included only once. To display the first image, we’d use the following CSS rule:

#help { background-image: url(sprite.png); background-position: -8px -8px; width: 16px; height: 16px; }

To display the second image, we’d use the following rule:

#rss { background-image: url(sprite.png); background-position: -8px -40px; width: 16px; height: 16px; }

At first glance, this technique might look a bit strange, but it’s really useful for decreasing the number of HTTP requests. The more images you combine this way, the better, because you’re cutting the request overhead dramatically. For an example of this technique in use “in the wild”, check out this image, used on Yahoo!’s homepage, or this one from Google’s.

In order to produce sprite images quickly, without having to calculate pixel coordinates, feel free to use the CSS Sprites Generator tool that I’ve developed. And for more information about CSS sprites, be sure to read Dave Shea’s article, titled CSS Sprites: Image Slicing’s Kiss of Death.

Use Post-load Pre-loading and Inline Assets

If you’re a responsible web developer, you’re probably already adhering to the separation of concerns and using HTML for your content, CSS for presentation and JavaScript for behavior. While these distinct parts of a page should be kept in separate files at all times, for performance reasons you might sometimes consider breaking the rule on your index (home) page. The homepage should always be the fastest page on your site — many first-time visitors may leave your site, no matter what content it contains, if they find the homepage slow to load.

When a visitor arrives at your homepage with an empty cache, the fastest way to deliver the page is to have only one request and no separate components. This means having scripts and styles inline (gasp)! It’s actually possible to have inline images as well (although it’s not supported in IE) but that’s probably taking things too far. Apart from being semantically incorrect, using inline scripts and styles prevents those components from being cached, so a good strategy will be to load components in the background after the home page has loaded — a technique with the slightly confusing name of post-load preloading. Let’s see an example.

Let’s suppose that the file containing your homepage is named home.html, that numerous other HTML files containing content are scattered throughout your site, and that all of these content pages use a JavaScript file, mystuff.js, of which only a small part is needed by the homepage.

Your strategy might be to take the part of the JavaScript that’s used by the homepage out of mystuff.js and place it inline in home.html. Then, once home.html has completed loading, make a behind-the-scenes request to pre-load mystuff.js. This way, when the user hits one of your content pages, the JavaScript has already been delivered to the browser and cached.

Once again, this technique is used by some of the big boys: both Google and Yahoo! have inline scripts and styles on their homepages, and they also make use of post-load preloading. If you visit Google’s homepage, it loads some HTML and one single image — the logo. Then, once the home page has finished loading, there is a request to get the sprite image, which is not actually needed until the second page loads — the one displaying the search results.

The Yahoo search page performs conditional pre-loading — this page doesn’t automatically load additional assets, but waits for the user to start typing in the search box. Once you’ve begun typing, it’s almost guaranteed that you’ll submit a search query. And when you do, you’ll land on a search results page that contains some components that have already been cached for you.

Preloading an image can be done with a simple line of JavaScript:

new Image().src='image.png';

For preloading JavaScript files, use the JavaScript include_DOM technique and create a new <a title="Look up the tag in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/script"><script> tag, like so:

var js = document.createElement('script'); js.src = 'mysftuff.js'; document.getElementsByTagName('head')[0].appendChild(js);

Here’s the CSS version:

var css  = document.createElement('link'); css.href = 'mystyle.css'; css.rel  = 'stylesheet'; document.getElementsByTagName('head')[0].appendChild(css);

In the first example, the image is requested but never used, so it doesn’t affect the current page. In the second example, the script is added to the page, so as well as being downloaded, it will be parsed and executed. The same goes for the CSS — it, too, will be applied to the page. If this is undesirable, you can still pre-load the assets using XMLHttpRequest.
JavaScript Optimizations

Before diving into the JavaScript code and micro-optimizing every function and every loop, let’s first look at what big-picture items we can tackle easily that might have a significant impact on a site’s performance. Here are some guidelines for improving the impact that JavaScript files have on your site’s performance:

  1. Merge .js files.

  2. Minify or obfuscate scripts.

  3. Place scripts at the bottom of the page.

  4. Remove duplicates.


// <![CDATA[
/*<![CDATA[*/// */
// ]]>

Merge .js Files

As per the basic rules, you should aim for your JavaScripts to make as few requests as possible; ideally, this also means that you should have only one .js file. This task is as simple as taking all .js script files and placing them into a single file.

While a single-file approach is recommended in most cases, sometimes you may derive some benefit from having two scripts — one for the functionality that’s needed as soon as the page loads, and another for the functionality that can wait for the page to load first. Another situation in which two files might be desirable is when your site makes use of a piece of functionality across multiple pages — the shared scripts could be stored in one file (and thus cached from page to page), and the scripts specific to that one page could be stored in the second file.

Minify or Obfuscate Scripts

Now that you’ve merged your scripts, you can go ahead and minify or obfuscate them. Minifying means removing everything that’s not necessary — such as comments and whitespace. Obfuscating goes one step further and involves renaming and rearranging functions and variables so that their names are shorter, making the script very difficult to read. Obfuscation is often used as a way of keeping JavaScript source a secret, although if your script is available on the Web, it can never be 100% secret. Read more about minification and obfuscation in Douglas Crockford’s helpful article on the topic.

In general, if you gzip the JavaScript, you’ll already have made a huge gain in file size, and you’ll only obtain a small additional benefit by minifying and/or obfuscating the script. On average, gzipping alone can result in savings of 75-80%, while gzipping and minifying can give you savings of 80-90%. Also, when you’re changing your code to minify or obfuscate, there’s a risk that you may introduce bugs. If you’re not overly worried about someone stealing your code, you can probably forget obfuscation and just merge and minify, or even just merge your scripts only (but always gzip them!).

An excellent tool for JavaScript minification is JSMin and it also has a PHP port, among others. One obfuscation tool is Packer — a free online tool that, incidentally, is used by jQuery.

Changing your code in order to merge and minify should become an extra, separate step in the process of developing your site. During development, you should use as many .js files as you see fit, and then when the site is ready to go live, substitute your “normal” scripts with the merged and minified version. You could even develop a tool to do this for you. Below, I’ve included an example of a small utility that does just this. It’s a command-line script that uses the PHP port of JSMin:

<?php include 'jsmin.php'; array_shift($argv); foreach ($argv AS $file) { echo '/* ', $file, ' */'; echo JSMin::minify(file_get_contents($file)), "\n"; } ?>

Really simple, isn’t it? You can save it as compress.php and run it as follows:

$ php compress.php source1.js source2.js source3.js > result.js

This will combine and minify the files source1.js, source2.js, and source3.js into one file, called result.js.

The script above is useful when you merge and minify as a step in the site deployment process. Another, lazier option is to do the same on the fly — check out Ed Eliot’s blog post, and this blog post by SitePoint’s Paul Annesley for some ideas.

Many third-party JavaScript libraries are provided in their uncompressed form as well as in a minified version. You can therefore download and use the minified versions provided by the library’s creator, and then only worry about your own scripts. Something to keep in mind is the licensing of any third-party library that you use. Even though you might have combined and minified all of your scripts, you should still retain the copyright notices of each library alongside the code.

Place Scripts at the Bottom of the Page

The third rule of thumb to follow regarding JavaScript optimization is that the script should be placed at the bottom of the page, as close to the ending </body> tag as possible. The reason? Well, due to the nature of the scripts (they could potentially change anything on a page), browsers block all downloads when they encounters a <a title="Look up the tag in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/script"><script> tag. So until a script is downloaded and parsed, no other downloads will be initiated.

Placing the script at the bottom is a way to avoid this negative blocking effect. Another reason to have as few <a title="Look up the tag in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/script"><script> tags as possible is that the browser initiates its JavaScript parsing engine for every script it encounters. This can be expensive, and therefore parsing should ideally only occur once per page.

Remove Duplicates

Another guideline regarding JavaScript is to avoid including the same script twice. It may sound like strange advice (why would you ever do this?) but it happens: if, for example, a large site used multiple server-side includes that included JavaScript files, it’s conceivable that two of these might double up. The duplicate script would cause the browser’s parsing engine to be started twice and possibly (in some IE versions) even request the file for the second time. Duplicate scripts might also be an issue when you’re using third party libraries. Let’s suppose you had a carousel widget and a photo gallery widget that you downloaded from different sites, and they both used jQuery. In this case you’d want to make sure that you didn’t include jQuery twice by mistake. Also, if you use YUI, make sure you don’t include a library twice by including, for example, the DOM utility (dom-min.js), the Event utility (event-min.js) and the utilities.js library, which contains both DOM and Event.
CSS Optimizations

Merge and Minify

For your CSS files you can follow the guidelines we discussed for JavaScripts: minify and merge all style sheets into a single file to minimize download size and the number of HTTP requests taking place. Merging all files into one is a trivial task, but the job of minification may be a bit harder, especially if you’re using CSS hacks to target specific browsers — since some hacks exploit parsing bugs in the browsers, they might also trick your minifier utility.

You may decide not to go through the hassle of minifying style sheets (and the associated re-testing after minification). After all, if you decide to serve the merged and gzipped style sheet, that’s already a pretty good optimization.

If you do decide to minify CSS, apart from the option of minifying manually (simply removing comments and whitespace), you can use some of the available tools, such as CSSTidy, PEAR’s HTML_CSS library (http://pear.php.net/package/HTML_CSS/), or SitePoint’s own Dust-me Selectors Firefox plugin.

Place Styles at the Top of the Page

Your single, gzipped (and optionally minified) style sheet is best placed at the beginning of the HTML file, in the <a title="Look up the tag in the SitePoint HTML Reference." href="http://reference.sitepoint.com/html/head"><head> section — which is where you’d usually put it anyway. The reason is that most browsers (Opera is an exception) won’t render anything on the page until the all the style sheets are duly downloaded and parsed. Additionally, none of the images referenced from the CSS will be downloaded unless the CSS parsing is complete. So it’s better to include the CSS as early on the page as possible.

You might think about distributing images across different domains, though. Images linked from the CSS won’t be downloaded until later, so in the meantime, your page can use the available download window to request content images from the domain that hosts the CSS images and is temporarily “idle”.

Ban Expressions

IE allows JavaScript expressions in CSS, like this one:

#content { left: expression(document.body.offsetWidth) }

You should avoid JavaScript expressions for a number of reasons. First of all, they’re not supported by all browsers. They also harm the “separation of concerns”. And, when it comes to performance, expressions are bad because they’re recalculated every time the page is rendered or resized, or simply when you roll your mouse over the page. There are ways to make expressions less expensive — you can cache values after they’re initially calculated, but you’re probably better off simply to avoid them.
Tools for Performance Optimization

A number of tools can help you in your performance optimization quest. Most importantly, you’d want to monitor what’s happening when the page is loaded, so that you can make informed decisions. Try these utilities:

Summary

Whew! If you’ve made it this far, you now know quite a lot about how to approach a site optimization project (and more importantly, how to build your next web site with performance in mind). Remember the general rule of thumb that, when it comes to optimization, you should concentrate on the items with the biggest impact, as opposed to “micro-optimizing”.

You may choose not to implement all the recommendations discussed above, but you can still make quite a difference by focusing on the really low-hanging fruit, such as:

  • making fewer HTTP requests by combining components — JavaScript files, style sheets and images (by using CSS Sprites)

  • serving all textual content, including HTML, scripts, styles, XML, JSON, and plain text, in a gzipped format

  • minifying and placing scripts at the bottom, and style sheets at the top of your files

  • using separate cookie-free domains for your components