Book Image

jQuery HOTSHOT

By : Dan Wellman
Book Image

jQuery HOTSHOT

By: Dan Wellman

Overview of this book

jQuery is used by millions of people to write JavaScript more easily and more quickly. It has become the standard tool for web developers and designers to add dynamic, interactive elements to their sites, smoothing out browser inconsistencies and reducing costly development time.jQuery Hotshot walks you step by step through 10 projects designed to familiarise you with the jQuery library and related technologies. Each project focuses on a particular subject or section of the API, but also looks at something related, like jQuery's official templates, or an HTML5 feature like localStorage. Build your knowledge of jQuery and related technologies.Learn a large swathe of the API, up to and including jQuery 1.9, by completing the ten individual projects covered in the book. Some of the projects that we'll work through over the course of this book include a drag-and-drop puzzle game, a browser extension, a multi-file drag-and-drop uploader, an infinite scroller, a sortable table, and a heat map. Learn which jQuery methods and techniques to use in which situations with jQuery Hotshots.
Table of Contents (18 chapters)
jQuery HOTSHOT
Credits
Foreword
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Creating a code wrapper and defining variables


All of our code will need to be contained within a wrapper function that is executed once the page has finished loading.

Prepare for Lift Off

The steps that we'll complete in this part of the project are as follows:

  • Add a wrapper function for our code that will execute as soon as the page has finished loading

  • Define the variables that we'll use throughout the script

Engage Thrusters

The first step is to create a wrapper function for our code that will be executed as soon as the page has loaded. Add the following code to a new script file called sliding-puzzle.js, which should be saved in the js directory we created earlier:

$(function () {

    //all our code will be in here...

});

Most jQuery code that we see in the wild resides within some kind of wrapper like this. Using $(function(){}); is a shortcut to jQuery's document.ready function, which is fired once the DOM for the page has loaded.

Tip

Using $

We wouldn't normally use $ in the global scope like this if we were sharing our code with other developers, as there may be other libraries on the page also using it. Best practice is to alias the $ character within an automatically invoked anonymous function, or an immediately invoked function expression if you prefer. This can be done using the syntax (function($) { … }(jQuery));.

Next we can set some variables near the top of the script file. This is so that we don't have lots of values that we may want to change later distributed throughout the file. Organization is one of the keys to writing maintainable code, and we should always strive to make our code, as well as our intentions, as clear as possible.

Next add the following code inside the function we just defined, replacing the comment shown in the previous code sample:

var numberOfPieces = 12,
    aspect = "3:4",
    aspectW = parseInt(aspect.split(":")[0]),
    aspectH = parseInt(aspect.split(":")[1]),
    container = $("#puzzle"),
    imgContainer = container.find("figure"),
    img = imgContainer.find("img"),
    path = img.attr("src"),
    piece = $("<div/>"),
    pieceW = Math.floor(img.width() / aspectW),
    pieceH = Math.floor(img.height() / aspectH),
    idCounter = 0,
    positions = [],
    empty = {
        top: 0, 
        left: 0,
        bottom: pieceH, 
        right: pieceW
    },
    previous = {},
    timer,
    currentTime = {},
    timerDisplay = container.find("#time").find("span");

These aren't all of the variables that we'll use, just the majority of them. The list also includes any variables that we'll need to use inside callback functions so that we don't run into scope issues.

Objective Complete - Mini Debriefing

The variables we defined first are a combination of simple (primitive) values and objects or arrays that we'll use throughout the code, and cached jQuery elements. For best performance when using jQuery, it's best to select elements from the page and store them in variables instead of repeatedly selecting them from the page.

Although none of our variables are directly assigned to window, and are therefore not actually global, because we are defining them right at the top of our outermost function, they will be visible throughout our code and we can consider them as global. This gives us the visibility of globals, without actually cluttering the global namespace.

Note

It is best practice to define variables at the top of the function they are scoped to because of a phenomenon known as hoisting, in which variables defined deep inside a function, inside a for loop for example, are "hoisted" to the top of the function in some situations, potentially causing errors that are hard to track down.

Defining variables at the top of the function where possible is a simple way to avoid this occurring and is considered a good practice when writing jQuery, or JavaScript in general.

Most of the variables are quite straightforward. We store the number of puzzle pieces we'd like to use and the aspect ratio of the image being used. It's important that the number of pieces can be equally divided by both the width and height components of the ratio.

We split the aspect ratio into its component parts using JavaScript's split() function and specifying the colon as the character to split on. We also use the JavaScript parseInt() function to ensure we end up with actual numbers and not strings in the aspectW and aspectH variables.

The next three variables are all different elements selected from the page that we need to manipulate. Following this is a new element that we create using jQuery.

Next we calculate the width and height each piece of the puzzle will need to be sized to, based on the width and height of the original image and the aspect ratio, and we initialize a counter variable that we'll use to add a unique, ordered id attribute to each puzzle piece. We also add an empty array called positions, which we'll use to store the top and left positions of each new piece.

We'll need a way of keeping track of the empty space as the pieces are moved around the board, so we create an object called empty and give it top, left, bottom, and right properties so that we'll know exactly where the blank is space at any given moment. We'll also want to keep track of the previous location of any given piece so we create an empty object called previous that we'll populate with properties when required.

The remaining three variables are all concerned with keeping track of the time it takes to solve the puzzle. We defined, but didn't initialize the timer variable that we'll use to store a reference to a JavaScript setInterval()-based timer later in the script. We also created an empty object called currentTime, which again we'll populate when required, and cached a reference to the element that we'll use to display the current time.