JavaScript

JavaScript Debugging in Internet Explorer

For those of us who have lamented the sad state of debugging in Microsoft's Internet Explorer (and no, the Microsoft Script Debugger doesn't count), some relief is here. Complementing the IE Developer Toolbar, the Microsoft Visual Studio 2008 Web Developer Express Edition (and previously the 2005 Express Edition) gives you full JavaScript debugging ability from within the VS development environment without needing the paid version. The only drawback vis-a-vis the professional edition is that the page must be launched from with the IDE (rather than from IE itself). A small price to pay for desperately needed functionality.

Here's some quick steps to get you started:

1. Download the Web Developer Express Edition for free (though registration is required to activate it).
2. Create an empty web site, File-->Web Site...-->Empty Web Site.
3. Deposit the files you wish to debug in the web site folder, and open the file you wish to debug. Place desired break points. (Or you can skip this step if you just intend to just navigate to a URL later.)
4. Click the "Start Debugging" button. If you skipped step #3 and wish to navigate to a URL, then you may want to put at least one debugger statement in your JavaScript code so that the debugger will stop at this statement. Breakpoints can then be set within the IDE elsewhere.
5. Controls are in the Debug menu. F10 will step over, F11 will step into, etc.
6. All the expected debugging views are there: Call Stack, Locals (variables), Watch, and so forth.

Not quite as convenient as having Firebug directly in your browser, but a first-class JavaScript debugger (as JavaScript debuggers go...) nonetheless.

How JavaScript Timers Work

Tagged:  

John Resig has posted a very interesting excerpt on JavaScript timers from his upcoming book, Secrets of the JavaScript Ninja, due out this fall. In his post, John covers timer delay and asynchronous events on a single thread, including three functions associated with timers and the differences between each:

  • var id = setTimeout(fn, delay); - Initiates a single timer which will call the specified function after the delay. The function returns a unique ID with which the timer can be canceled at a later time.
  • var id = setInterval(fn, delay); - Similar to setTimeout but continually calls the function (with a delay every time) until it is canceled.
  • clearInterval(id); - Accepts a timer ID (returned by either of the aforementioned functions) and stops the timer callback from occurring.

Here's a quick summary of the key points of the post:

* JavaScript engines only have a single thread, forcing asynchronous events to queue waiting for execution.
* setTimeout and setInterval are fundamentally different in how they execute asynchronous code.
* If a timer is blocked from immediately executing it will be delayed until the next possible point of execution (which will be longer than the desired delay).
* Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified delay).

Read the full post for more detail on these key points and to better understand how JavaScript timers work.

Creating a Simple JavaScript Game Board

Over at the Web Cash blog they have posted two tutorials on Game development in JavaScript, Ajax and PHP. The first tutorial explains the concept and describes how to make a game board.

Below is an excerpt from the first tutorial.

Game Development with JS, AJAX, and PHP

How can we use JS and PHP - connected through AJAX - to develop an online game?

Javascript’s main use for us is to create an interface for the game. Through Javascript we can capture user input - i.e. mouse clicks and text. We can also alter the game’s output - changing the HTML of the page, adding images, and moving things around. Javascript will provide a lot of the front end work.

PHP, on the other hand, is a more robust language for dealing with the logic of the game. PHP could be useful for developing an AI and evaluating winning conditions. It also offers a great way to store information for later use through flat files or database integration.

If we’re going to use both Javascript and PHP, we’ll need to use AJAX. This is the glue that holds the whole thing together. It will send input from the main Javascript to the PHP processing scripts. The PHP script will then send info back to the Javascript and it will alter the page’s layout accordingly.

Read the full first tutorial here.

The second tutorial goes into more detail as to how you would start creating a simple game. By the end of the tutorial you have a complete simple tic-tac-toe game (the game needs more logic added to be finished, but the concept is there).

Below is an excerpt from the second tutorial.

Creating Graphics

Tic Tac Toe Circle ImageI created two images in Inkscape to use for this board. Each is a 50×50 png file - with a gray background and a black border. The actual token (the circle or cross) is red and laid on top of the gray background.

Tic Tac Toe Cross ImageI’m no great artist, but these should work for a functional demo. We can worry about making nice circle and cross tokens later. I think getting the game working is more important than making it pretty from the get-go.

Turning Our .js Script into a Class

In making this a functional board, I also converted the script into an actual class. The script may end up being somewhat large and unwieldy - and an object oriented approach may help us keep it tidy and clean. Or it may add a lot of overhead… but I like objects.

In our HTML file, we’ll create the object like this.

<script type="text/javascript">
var tictactoe = new game();
</script>

In the attached .js file, we actually define the game object. Here’s part of the object definition.

function game() {
  //  Array to hold the bgImgs
  this.bgImgs = new Array();
    this.bgImgs[0] = 'tttcircle.png';
    this.bgImgs[1] = 'tttcross.png';

 
  //  Player information			
  this.currentPlayer = 0;
  this.players = new Array();
    this.players[0] = "Player One";
    this.players[1] = "Player Two";

 
   return true;

This class constructor does some of the initialization for us.

First, it creates an array with background images. At the moment we’re only using two images. However, this technique would be useful if you had a more complex map - with 10-15 images you could lay over a div.

Second, we create some player information variables. The ‘currentPlayer’ property is going to track whether the ‘cross’ or ‘circle’ player is currently taking a turn. The ‘players’ array will just hold the names of those players for now.

The Background Image Changing Function

One of the major methods of this class will be changeBackground(). Just like in the previous example, this method will change the background style of a given div tag. This way we can change it from an open square to a circle or cross token.

  this.changeBackground = function (boxId) {
    var box = document.getElementById('box-' + boxId);
    box.style.background = 'transparent url(' + 
      this.bgImgs[this.currentPlayer] + ') top left no-repeat';

 
    box.removeAttribute('onClick');
 
    this.changePlayer();
  }

This should be pretty straightforward. We’re storing the ‘div’ element in the ‘box’ variable. We’re then setting the ‘background’ style as we would in a css style. Remember that we stored the background images in an array (this.bgImgs) and this.currentPlayer corresponds to a key in the this.bgImgs array (either 0 or 1).

The ‘box.removeAttribute()’ method is removing ‘onClick’ from that div. We can’t use a square a second time, so we might as well eliminate the onClick handler altogether.

Finally, this.changePlayer() is calling a new method. This is going to help us switch from Player One’s turn to Player Two’s turn.

One Turn to Another - this.changePlayer()

The last method we need to declare for this class at the moment is changePlayer.

This will toggle the active player - which in turn affects whether a circle or cross is placed on the board. For some added effect, we’ll also create a new html element to display a message that says who’s turn it is.

  this.changePlayer = function () {
    //  Switch the active player

    if (this.currentPlayer == 0) {
      this.currentPlayer = 1;
    } else {

      this.currentPlayer = 0;
    }
 
    //  Get a reference to our 'message' element and create the message
    var box = document.getElementById('message');
    var msg = "It is " + this.players[this.currentPlayer] + "'s turn.";
    var txt = document.createTextNode(msg);

 
    //  Erase any existing text
    while (box.hasChildNodes()) {
      box.removeChild(box.lastChild);
    }

 
    //  Add the text node (our message) to our element
    box.appendChild(txt);
  }

Again, this is pretty straightforward. The DOM functions are amazingly simple - once you see how they work.

‘box’ is a reference to our element (id = message). The msg variable is a temp variable I created to hold the string. The ‘createTextNode’ method creates a new block of text (with our msg) that we can then insert into an HTML element.

The while() loop is simply there to erase any old text. As long as our ‘box’ element has any child nodes inside of it (text or other HTML tags), the loop will execute and delete one of those child nodes each time. This way we have a clean slate on which to write down who’s turn it is.

Read the full second tutorial here.

Although the tutorial only shows a simplistic tic-tac-toe game you could use the concepts as a starting point to build your own web games. As always if you have made any cool games we would love to hear about them either in the comments or you can write a blog post about it using your free Ajaxonomy account.

Upgrading to Prototype 1.6 just got easier

Here's some good news for those of you who still need to upgrade your Prototype 1.5 code to Prototype 1.6. Tobie Langel, a core developer on the Prototype team, has developed a script that will warn you of any deprecations or API changes between versions. If you don't know why you should upgrade to 1.6, check out the release info for version 1.6, including the changelog and release notes for 1.6.0_rc0 and 1.6.0_rc1. The script is used with Firebug and is Firefox only, but once you've upgraded, you're good to go in all browsers.

Using the script is easy. To migrate a page from 1.5 to 1.6:

  1. Find the script tag that references prototype.js. Change the path to point to the 1.6.0.2 version (or else overwrite the existing prototype.js with the new version).
  2. On the very next line, add a script tag that references deprecation.js.
  3. Develop your app as normal.

When your code calls a method that’s been deprecated, replaced, or modified, the script will log a warning or error to your Firebug console. Clicking its hyperlink will take you to the deprecation script itself, which isn’t all that helpful; but the message itself will contain a stack trace that points to the source of the error.

Download the deprecation script.

Read more about the script over at the Prototype blog.

script.aculo.us Tutorial

The folks over at Tutorials Point have posted a good tutorial for learning script.aculo.us on their site. The tutorial does well to cover the framework, includes lots of codes examples, and even has a W3C Schools style "try-it-yourself" editor to let you play with the demos. Get started with the tutorial by accessing the sections below:

  1. Short Overview: Gives a brief overview of script.aculo.us.
  2. Major Modules : List out all the modules supported by script.aculo.us.
  3. Visual Effects : Gives complete understanding on creation of visual effects using script.aculo.us.
  4. Drag & Drop: Explains Drag and Drop functionality in detail.
  5. Sorting Elements: Learn how to sort various elements using drag and drop functionality.
  6. Create Sliders: Yes, you can provide a multi purpose slider at your web site
  7. Auto Completion: Explains how to implement Auto Completion
  8. In Place Editing: Click and update in place using script.aculo.us.

If you step through the tutorial, let us know what you think, and if you know of any other good tutorials you'd like to share, send them our way!

Cross-Window Messaging

Tagged:  

Over at John Resig's blog, he has posted an interesting article about cross-window messaging. The method is part of the HTML 5 Specifications and is available with Firefox 3.

The new method allows you to access all windows, including iFrames, Frames, Popups and the Current Window. The new call would create a DOM event, in the other window, which allows for messaging between the two windows.

Below is an excerpt from the post.

Obviously communicating in a cross-domain fashion is prone to abuse so there's additional information passed along that can be used to verify the integrity of the message. The full list of properties include:

* .data - A string holding the message passed from the other window.
* .domain - The domain name of the window that sent the message.
* .uri - The full URI for the window that sent the message.
* .source - A reference to the window object of the window that sent the message.

The last property is especially important as it allows for two-way communication to occur between these windows.

Simple Demo>

I've constructed a simple demo that you can try (requires a nightly of Firefox 3) in which you can send a message - through an iframe - to another domain, having the results be received and rendered by it. Thus, this demos consists of two pages: One acting as the sender (on ejohn.org), one acting as the receiver (on dev.jquery.com).

This first page is the sender - it's calling postMessage (sending the textual message) and also holds the iframe within which the receiving window is held.

<iframe src="http://dev.jquery.com/~john/message/" id="iframe"></iframe>
<form id="form">
  <input type="text" id="msg" value="Message to send"/>
  <input type="submit"/>
</form>
<script>
window.onload = function(){
        var win = document.getElementById("iframe").contentWindow;
        document.getElementById("form").onsubmit = function(e){
                win.postMessage( document.getElementById("msg").value );
                e.preventDefault();
        };
};
</script>

The follow page is the receiver - it has an event listener bound which watches for messages being passed to it and injects them in to the DOM.

<b>This iframe is located on dev.jquery.com</b>
<div id="test">Send me a message!</div>
<script>
document.addEventListener("message", function(e){
        document.getElementById("test").textContent =
                e.domain + " said: " + e.data;
}, false);
</script>

You can read the full post here.

This new method could make for some interesting applications. I could see your del.icio.us account sending messages back and forth from your Digg account in two different windows all on the client side. That is of course if the cross domain settings can be worked out.

Hack the Day Away with Google

Tagged:  

If you are in the Mountain View area you can attend a "Hackathon" with Google on Friday, February 29th from 2pm - 10pm (there are two sessions one from
2pm - 5:30pm and another from 6pm - 10pm). This "Hackathon" is centered around Ajax development and is a great time to learn the below API's from the experts.

Google Gears [http://code.google.com/apis/gears/]
Google AJAX Search/Feeds [http://code.google.com/apis/ajaxsearch/]
Google Gadgets [http://code.google.com/apis/gadgets/]
Google Maps [http://code.google.com/apis/maps/index.html]

There will be a quick over view of the API's before the "Hackathon" starts. A few other things that all of we developers like is that there will be free food, prizes and schwag! Also, make sure to bring your laptop as laptops will not be provided.

You can read more about the event here.

To RSVP your spot click here.

Multi-player Ajax Games

Today I came across an interesting article about creating multi-player video games using Ajax. The article mainly deals with how you would send data to and from the server and also touches on keeping the game in sync on multiple clients.

The below code is how the post purposes that you would send data to the server side (this code uses a hand rolled Ajax call, but you could change it to use a library).

var httpSend = null;
var httpGet = null;

function send(action)
{
httpSend=GetXmlHttpObject();
if (httpSend==null){alert (?Your browser does not support AJAX!?);return;}

var url=?send.php?;
url=url+??action=?+action;
url=url+?&p=?+player;
url=url+?&g=?+gameid;
url=url+?&sid=?+Math.random();
httpSend.onreadystatechange=stateSend;
httpSend.open(?GET?,url,true);
httpSend.send(null);
}

function get()
{
if(httpGet != null) { return 0; }

httpGet=GetXmlHttpObject();
if (httpGet==null){alert (?Your browser does not support AJAX!?);return;}

var url=?get.php?;
url=url+??sid=?+Math.random();
url=url+?&p=?+player;
url=url+?&g=?+gameid;
httpGet.onreadystatechange=stateGet;
httpGet.open(?GET?,url,true);

httpGet.send(null);
}

function stateSend() {
if (httpSend.readyState==4){}
}

function stateGet() {
if (httpGet.readyState==4)
{
str = httpGet.responseText;
if(str != ?){
eval(str);
}
httpGet = null;
}
}

function GetXmlHttpObject() {
var xmlHttp=null;
try {
xmlHttp=new XMLHttpRequest();
}
catch (e) {
try {
xmlHttp=new ActiveXObject(?Msxml2.XMLHTTP?);
}
catch (e) {
xmlHttp=new ActiveXObject(?Microsoft.XMLHTTP?);
}
}
return xmlHttp;
}

The following code would be on the server side to receive messages. In the case of this example the code is PHP and the file is called Get.php

<?php
include(?config.php?);
$p = $_GET[?p’];
$g = $_GET[?g’];
$action = ?;
$query = mysql_query(?SELECT * FROM actions WHERE id = ?.$g);
$row = mysql_fetch_array($query);
$action = $row[$p];
$action = stripslashes($action);
$str = ?update actions set `?.$p.?` = ? where id = ?.$g;
mysql_query($str);
echo $action;
?>

The following code would be on the server side to send messages. In the case of this example the code is PHP and the file is called Send.php

<?php
include(?config.php?);
$p = $_GET[?p’];
$g = $_GET[?g’];
if($p == 1)
{
$b = 2;
}
elseif($p == 2)
{
$b = 1;
}
$action = $_GET[?action?];
$action = addslashes($action);
$query1 = mysql_query(?select * from actions where id = ?.$g);
$row = mysql_fetch_array($query1);
$str = $row[$b];
$str = $str . $action;
$str = ?UPDATE actions SET `?.$b.?` = ??.$str.?? where id = ?.$g;
$query = mysql_query($str);
if(!$query)
{
echo mysql_error().$str;
}
else
{
echo 0;
}
?>

You can read the full post here

The post also touches on the possibility of sending data via a text string. I personally think that for multi-player games JSON is a perfect data transfer method. Unlike XML there is not a large overhead and unlike sending data via a text string there is no parsing needed on the client which should help performance. This post is interesting as I think that Ajax can be a very useful method of transferring data for multi-player games.

IncludeJS - include and compress JavaScript easily

Justin Meyer has been working on a JavaScript library named IncludeJS and has released a 0.1 alpha 1 Developer package. IncludeJS lets developers include and compress JavaScript files easily. The hope for the library is "to bridge the gap between frameworks like jQuery/Prototype which guess at what you will most likely need, and frameworks like MooTools, which are great if you know exactly what you want and don't need to look in the source."

IncludeJS was originally a component of JavaScriptMVC - an open source JavaScript Model-View-Controller framework. The framework is going through some major changes and individual components are being extracted to make each individually useful.

Features of IncludeJS:

Relative paths.

Instead of including files relative to the current page's url,
IncludeJS includes files relative to your JavaScript files' urls.
Forget about scanning the page's script tags for your library's path.
IncludeJS lets you organize your scripts however you want.

Dynamic compression.

IncludeJS uses Dean Edwards packer
to automatically compress your
JavaScripts. Unlike server-side compression scripts,
compression is determined at runtime. This makes
it easy to compress large libraries with optional plugins.

Highlights.

- Consistant include order (last-in-first-out)
- FF 1.5+, IE 6+, Opera 9, Safari 3.
- Works with libraries like Prototype and jQuery.
- MIT license.
- 3 KB compressed.
- Files visible in Firebug.

Usage

1) Include the library in your page

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

2) Include JavaScript files with the include function, files are relative to the including file and will be included in LIFO [last-in-first-out] order.

<script type="text/javascript">
   include( 'javascripts/prototype',
            'javascripts/myapplication'
   )
</script>

3) Compress your app by adding the line:

include.setup('compress')

before your includes, after the page loads you're presented with a compressed version of the code.

<script type="text/javascript">
   include.setup('compress')
   include( 'javascripts/prototype',
            'javascripts/myapplication'

   )
</script>

4) Run it! After you've saved the compressed version of the code, change the "compress" argument to "production" and specify the path to the newly created library as a second argument.

<script type="text/javascript">
   include.setup('production','path/to/prod')
   include( 'javascripts/prototype',
            'javascripts/myapplication'
   )

</script>

Visit the IncludeJS Homepage

Check out the demo over at JavaScriptMVC.com

More JavaScript/Ajax Cheatsheets

Tagged:  

Scott Klarr has posted a collection of some JavaScript/Ajax cheatsheets on his blog.

The cheatsheets include:

  • Javascript Cheat Sheets
  • jQuery Cheat Sheets
  • Scriptaculous Cheat Sheets
  • Prototype Cheat Sheets
  • Microsoft Ajax Library Cheat Sheets
  • Yahoo YUI Cheat Sheets
  • ...and more...
  • Click here to read the post and to download the cheatsheets.

Syndicate content