Disable cache in web browsers

Internet Explorer

1, Press F12 to open Developer Toolbar
2, In the Menu select Cache and click Always Refresh Cache from Server

Google Chrome

1, Press F12 to open Developer Tools
2, Press the gearwheel icon in the bottom right corner
3, Check Disable cache

Firefox

1, Type “about:config” in the address field
2, Type “browser.cache.disk.enable” in the filter field
3, Double click the preference row to to toggle the value to false

Opera

1, Open the preferences window (Ctrl+F12)
2, On the Advanced tab: select History
3, Change the value of Disc cache to Off

Safari

1, Press the Menu Icon next to the search field.
2, Expand the Develop menu option
3, Click Disable Caches

jQuery Quick Tip: Toggle

I often stumble upon code that look like this:

if(someBooleanValue) {
	$('#my-element').show();
} else {
	$('#my-element').hide();
}

This can be written in a shorter, smarter way by passing a boolean value to the toggle method. The element will then be displayed if the value is true and hidden if the value is false.

$('#my-element').toggle(someBooleanValue);

The same goes for toggleClass where you pass the class name as first argument and boolean value as second argument.

$('#my-element').toggleClass('my-class', someBooleanValue);

Prevent screen readers from reading content

You can prevent screen readers like JAWS and NVDA from reading the contents of an element by adding the role=”presentation” attribute. When a screen reader encounters an element with this attribute they will ignore the contents of the element and skip to the next element.

It’s a good idea to add this attribute to elements that are only important for visual appearance, like icons or a change text size function.

Adding this attribute will also remove the element from the tab order.

Useful JavaScript Array Extension Methods

These are some useful JavaScript Array Metods I use often. Some of them are implemented in modern browsers but it can be useful to supply the functionality for older browsers.

// Array.indexOf (Implemented in JavaScript 1.6)
// Returns the first index of the item in the array
if(!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(item) {
        var i, l;

        for(i = 0, l = this.length; i < l; i++) {
            var t = this[i];
            if(item === t) {
                return i;
            }
        }

        return -1;
    };
}

// Usage: Returns 1
var letterArray = [ 'a', 'b', 'c', 'd' ];
letterArray.indexOf('b');
// Array.lastIndexOf (Implemented in JavaScript 1.6)
// Returns the last index of the item in the array
if(!Array.prototype.lastIndexOf) {
    Array.prototype.lastIndexOf = function(item) {
        var i;

        for(i = this.length; i <= 0; i--) {
            var t = this[i];
            if(item === t) {
                return i;
            }
        }

        return -1;
    };
}

// Usage: Returns 2
var numberArray = [ 1, 6, 1, 3 ];
numberArray.lastIndexOf(1);
// Array.indexOfObjectProperty
// Returns the  index of the first object in the array that has a property with the specified value
if(!Array.prototype.indexOfObjectProperty) {
    Array.prototype.indexOfObjectProperty = function(name, value) {
        var i, l, item;

        for(i = 0, l = this.length; i < l; i++) {
            item = this[i];

			if(name in item && item[name] === value) {
				return i;
			}
        }

        return -1;
    };
}

// Usage:
var personArray = [
	{ name: 'Bob', age: '33' },
	{ name: 'John', age: 20 },
	{ name: 'Leia', age: 28 }
];
// Would return 1
personArray.indexOfObjectProperty('name', 'John');

// Would return -1
personArray.indexOfObjectProperty('name', 'Kenny');
personArray.indexOfObjectProperty('shoeSize', '11');
// Array.forEach (Implemented in JavaScript 1.6)
// Runs a method for each item in the array
if(!Array.prototype.forEach) {
    Array.prototype.forEach = function(func,thisElement) {
        var i, l;

        thisElement = thisElement || this;

        for(i = 0, l = this.length; i < l; i++) {
            func.call(thisElement, this[i], i, this);
        }
    };
}

/*
Usage: Would print:
 Red: 0 Red,Green,Blue
 Green: 1 Red,Green,Blue
 Blue: 2 Red,Green,Blue
*/
var colorArray = [ 'Red', 'Green', 'Blue' ];
colorArray.forEach(function(value, index, thisElement) {
    document.write(value + ": " + index + ' ' + thisElement + '<br>');
});
// Array.remove
// Removes the item from the array and returns it
if(!Array.prototype.remove) {
    Array.prototype.remove = function(item) {
        var index = this.indexOf(item);

        if(index >= 0) {
            return this.splice(index, 1);
        }

        return null;
    }
}

// Usage: Would print: "Ford,Toyota"
var carArray = [ 'Ford', 'Volvo', 'Toyota' ];
carArray.remove('Volvo');
document.write(carArray);
// Array.insert
// Adds item to array at the supplied index or at the beginning of the array
if(!Array.prototype.insert) {
    Array.prototype.insert = function(item, index) {
		index = index || 0;
        this.splice(index, 0, item);
    }
}

// Usage: Would print "Badger,Bear,Wolf,Shark"
var animalArray = [ 'Bear', 'Shark' ];
animalArray.insert('Badger');
animalArray.insert('Wolf',2);
document.write(animalArray);

Scroll to ValidationSummary After Validation

This is a script i put together that scrolls to an ASP.NET ValidationSummary when the page is validated on the client side. This is useful when you have long forms and the ValidationSummary is outside of the browsers visible area.

// Hookup for .NET's client validation to focus validation summary after validation
(function validationHookup() {
	if (window.ValidationSummaryOnSubmit) {
		// Save a reference to the original method
		var originalValidationSummaryOnSubmit = ValidationSummaryOnSubmit;

		ValidationSummaryOnSubmit = function (validationGroup) {
			// Call the original method
			originalValidationSummaryOnSubmit(validationGroup);

			// Loop each validation summary
			for (var i = 0, l = Page_ValidationSummaries.length; i < l; i++) {
				var summary = Page_ValidationSummaries[i];

				// Find the summary for the current validationGroup
				if (IsValidationGroupMatch(summary, validationGroup)) {
					// Scroll to the ValidationSummaryElement
					summary.scrollIntoView();
					// Change the hash tag value of the URL to the ValidationSummary's ID
					//location.href = '#' + summary.id;
				}
			}
		}
	}
})();

You can use the DOMElements scrollIntoView method to scroll to the ValidationSummary or you can change the anchor URL to the ValidationSummary element’s ID.

Creating Games With HTML5 Canvas Part 4: Logic and collisions

In this part of the tutorial, which is the final one, we’ll add some more logic to the Snake game and add food for the snake to eat.

First we’ll add logic to make sure that the snake can’t go outside the canvas area. We will also add logic so the snake can’t hit any part of it’s body.

Add a new property to the Snake object called dead.

this.dead = false;

Add a check at the first line in the Snake’s logic method. Nothing should happen if the snake has died.

// Nothing should happen if the snake is dead
if(this.dead) {
   return;
}

Then add logic to the end of the method. If the snake goes outside the canvas area or if the snake hits any part of it’s body the game is over.

// Keep the snake inside bounds of the canvas area
if(this.x < 0 || this.x + Settings.objSize > Settings.canvasSize || this.y < 0 || this.y + Settings.objSize > Settings.canvasSize) {
   this.dead = true;
}

// Prevent snake from hitting any part of it's body
if(this.bodyCollision(this.x, this.y)) {
   this.dead = true;
}

We create a new method for the Snake object that checks if any part of the snakes body is at the the x and y position. We loop through all body objects except the head and return true if any object has the same x and y coordinates as the supplied arguments.

// Check if any part of the snakes body is located at x and y
this.bodyCollision = function(x, y) {
   for(var i = 0; i < this.bodyObjects.length - 1; i++) {
       var obj = this.bodyObjects[i];
       if(obj.x === x && obj.y === y) {
           return true;
       }
   }

   return false;
};

It’s time to add food. Add a food property to the Game object.

food: null

Add two methods to the Game object: getRandomPosition and spawnFood.

GetRandomPosition returns a random position based on the canvas width and height. SpawnFood creates a new object that represents a food object at a random position. It will also make sure that the snake isn’t located at the position.

// Gets a random position
getRandomPosition: function() {
   var xIndex = Settings.canvasSize / Settings.objSize,
       yIndex = Settings.canvasSize / Settings.objSize,
       x = Math.floor(Math.random()*xIndex) * Settings.objSize,
       y = Math.floor(Math.random()*yIndex) * Settings.objSize;

   return [x,y];
},

// Spawns a new food object at a random position.
spawnFood: function() {
   var pos = this.getRandomPosition();

   // Make sure it doesn't spawn on the snake
   while(this.snake.collision(pos.x, pos.y) || this.snake.bodyCollision(pos.x, pos.y)) {
       pos = this.getRandomPosition();
   }

   this.food = new Object(pos[0], pos[1], Settings.foodColor);
}

We need to change the logic of the Snake object to check if the snake has eaten a food object. Add a check at the last row of the logic method.

// Check if the snake is at the same location as a food object
if(this.collision(game.food.x, game.food.y)) {
this.hasEatenFood = true;
}

In the beginning of the logic method we reset the property.

this.hasEatenFood = false;

Add code to the Games Logic method to check if the snake has eaten food and generate new food.

if(this.snake.hasEatenFood) {
   this.spawnFood();
}

Now we’ll have a look at the draw methods. First in the Game objects draw method add code to draw the food.

this.food.draw(this.context);

Change the Snake objects draw method to look like this. The method returns immediately if the snake is dead. If not a new object is added to the body. Since the body should grow by one if the snake has eaten we only remove an object if hasEatenFood is false.

// Overrides draw method - Draw all the snakes body objects on the screen
this.draw = function(context) {
   if(this.dead) {
       return;
   }

   var newObj = new Object(this.x, this.y, Settings.snakeColor), // Get a new object at the snakes current position
       objToRemove;

   // Add the new object to the snakes body
   this.bodyObjects.push(newObj);

   // Draw the new object on the screen
   newObj.draw(context);

   // Erase the last object
   if(!this.hasEatenFood) {
       objToRemove = this.bodyObjects.shift(); // Remove the last item
       objToRemove.erase(context);
   }
};

The game should now be more or less complete. Let’s add some final touches. Add a div element with the id message where we’ll display the current score.

<div id="message"></div>

Add a score property to the Game object.

score: 0

Change the Game objects logic method to look like this. We display the current score if the snake has eaten food. If the snake is dead we display Game over.

logic: function() {
	this.snake.logic(this);

	// Display game over if snake is dead or update score and spawn new food if snake has eaten
	if(this.snake.dead) {
		this.showMessage('Game over! Score: ' + this.score);
	}
	else if(this.snake.hasEatenFood) {
		this.score += 10;
		this.showMessage('Score: ' + this.score);
		this.spawnFood();
	}
}

Then add a method to the Game object to display messages.

showMessage: function(msg) {
   document.getElementById('message').innerHTML = msg;
}

Now let’s add a button to reset the game. Add a button element to the page.

<button id="reset">Reset game</button>

Then add a reset method to the Game object. We clear the current interval reference to stop the main loop and reset score and message. Then we start the game again.

reset: function() {
   clearInterval(this.interval);
   this.score = 0;
   this.showMessage('Score: ' + this.score);
   this.start(this.canvas.id);
}

Finally add a handler for the reset button’s click event at the end of the document to reset the game.

document.getElementById('reset').onclick = function() {
   Game.reset();
};

The game is now done. View the demo and final code here.