Friday, 1 August 2008

JavaScript™ Phrasebook: Essential Code and Commands

Just now i completed reading JavaScript™ Phrasebook: Essential Code and Commands By Christian Wenz

Nice book written By Christian Wenz.Especially i liked examples from his book.

I wanted to share few important points i found from this book.

1) JavaScript is a client-side scripting languagethat means a language that runs on the client side, within a web browser.If the browser supports the language, JavaScript grants access to the current page and lets the script determine properties of the client, redirect the user to another page, access cookies, and do much more.

2) The birth of JavaScript was in September 1995, when version 2.0 of the Netscape browser was released, the first version to come with the scripting language. Back then, the name of the language was first Mocha and then, when released, LiveScript; but Netscape made a marketing deal with Sun (creator of Java) and renamed the language to JavaScript in December of that year.

3) Several browsers do support JavaScript. Usually, you have to support most of them. For instance, the website http://marketshare.hitslink.com/report.aspx?qprid=3 shows that in March 2006, Internet Explorer and Firefox together accounted for close to 95% of the browser market share, with Safari following (slightly over 3%). Netscape browsers held about 1% and Opera had about half a percent, which was about the same as all other browsers (including Konqueror) had together.

4) By accident, a solution for parallel installing several IE versions was found. You can find the original description of that on http://labs.insert-title.com/labs/Multiple-IEs-in-Windows_article795.aspx and more information at http://www.positioniseverything.net/articles/multiIE.html.

5) Dynamically Loading JavaScript Files

Sometimes it is necessary to load JavaScript code on demand, while a site is running. For instance, depending on user input, a specific external JavaScript file must be loaded.

One attempt is to use document.write() to dynamically add a new script element to the page. However, this fails with some browsers and also is not considered good style. A much better solution is to use DOM. First, you create a new script element and set the appropriate attributes. Then, you add this element to the page's DOM. Usually, the code is put in the head section of the page.

Example Code alerts "Welcome to JavaScript!"

scriptdynamic.html


<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script language="JavaScript" type="text/javascript">
var s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("language", "JavaScript");
s.setAttribute("src", "script.js");
document.getElementsByTagName("head")[0].appendChild(s);
</script>
</body>
</html>


script.js


window.alert("Welcome to JavaScript!");


6) Using JavaScript Pseudo URLs

Another way to call JavaScript code is to use a pseudo URL. When a URL that begins with
javascript: 
is loaded, the code behind that is executed, as can be seen in the preceding code (file url.html).


<a href="javascript:window.alert('Welcome to JavaScript!');">click here for a surprise</a>


Warning

When the code after the javascript: URL prefix returns something, the result is printed to the screen. Usually, this is not desirable. You can use the special JavaScript function void() to avoid this:


javascript:void(code_that_would_return_something());


7) When JavaScript is used together with links, the following does not work fully as expected:

8) Displaying the Modification Date of the Page

Whenever a web server sends a resource to the client, it also sends the date the document was modified the last time. Usually, the web server takes this information from the file system, but this header can also be modified or just not sent. But anyway, you can use this information, for instance as shown in the preceding code. Therefore, you can have a more or less realistic modification date on your page.


document.write(document.lastModified);


9) Retrieving GET Parameters

Usually, GET information is evaluated on the server side, but JavaScript does also have access to this information via its location.search property. However, the data there is in name-value pairs. The following code decodes this data by using the JavaScript split() method. The resulting associative array is then shown, just to prove that it works as expected;

querystring.html


<script language="JavaScript" type="text/javascript">
var getdata = [];
alert(location.search);
if (location.search.length > 1) {
var ls = location.search.substring(1);
var namevalue = ls.split("&");
for (var i=0; i<namevalue.length; i++) {
var data = namevalue[i].split("=");
getdata[data[0]] = data[1];
}
}

var
s = "";
for
(var el in getdata) {
s += el + ": " + getdata[el] + "\n";
}
alert(s);
</script
>




when run as file:///C:/querystring.html?one=1&two=2

alerts

?one=1&two=2
one=1
two=2

10) Stretching Graphics

Sometimes it is not even necessary to create several graphics to build an animation. Sometimes just stretching an image can create a nifty effect. Usually, this does not fare too well on the Web, since only bitmap file formats are supported (except for Flash or SVG, which is not available across browsers in their default setup). Therefore, stretching a graphic instructs the browser to calculate additional image information. Usually, this is done by copying pixels.

In the case of a progress bar, a simple graphic can suffice. In a simple example, use a 1x1-pixel image. If it is used in the HTML page with a width of 20 pixels and a height of 10 pixels, you get a 20x10-pixel image. By animating the width of the image with JavaScript, you can get the impression of a moving progress bar.

Example:


<script language="JavaScript" type="text/javascript">
function progress() {
if (document.images["bar"].width < 200) {
document.images["bar"].width += 5;
document.images["bar"].height = 5;
} else {
clearInterval(ID);
}
}

var
ID;
window.onload
= function() {
ID = setInterval("progress();", 500);
}
</script
>

<img src="black.gif" name="bar" />


The 1x1 image has been stretched dynamically by JavaScript. The progress() function is called every 500 millisecond, thanks to the setInterval() call. After the progess bar has reached its maximum length (in this example, arbitrarily 200 pixels), the animation is stopped with clearInterval().

11) Visualizing the Page Loading State with a Progress Bar

Whether or not a page has been completely loaded cannot be determined by JavaScript alone, but at least it can be sufficiently estimated. The complete property of an image provides a Boolean value telling whether the image has been completely loaded. Also, an image supports the load event, so onload can be used to trigger code execution after the image has been loaded.

The following code iterates through all images on the page and counts how many of them have been completely loaded. This generates an estimated percentage of how much of the page has been fully loaded. (Of course, not included are applets and embedded media; also, the image file sizes are not taken into account.)


<script language="JavaScript" type="text/javascript">
function showprogress() {
if (document.images.length == 0) {
return false;
}
var loaded = 0;
for (var i=0; i<document.images.length; i++) {
if (document.images[i].complete) {
loaded++;
}
}
var percentage = Math.round(100 * loaded / document.images.length);
document.getElementById("progress").innerHTML =
percentage + "% loaded";
if (percentage == 100) {
window.clearInterval(ID);
}
}

var
ID = window.setInterval("showprogress();", 500);
</script
>

<p id="progress">0% loaded</p>
<img src="gfx.php?wait=1" />
<img src="gfx.php?wait=3" />
<img src="gfx.php?wait=5" />


12) Accessing CSS Styles

JavaScript can set any CSS commands and is "almost" using the name of the CSS command as the JavaScript property. However, there is a problem: Some characters, like the dash, are not allowed within a JavaScript property. But many CSS commands like, for instance, font-weight, do have dashes in them. Therefore, the JavaScript language uses a lowerCamelCase syntax: Every component starts with an uppercase letter, but not the very first one. So the CSS command font-weight can be set using the fontWeight property.


<script language="JavaScript" type="text/javascript">
function makeBold() {
document.getElementById("para").style.fontWeight = "bold";
window.setTimeout("makeLighter();", 1000);
}

function makeLighter() {
document.getElementById("para").style.fontWeight = "lighter";
window.setTimeout("makeBold();", 1000);
}

window.onload = makeBold;
</script>
<p id="para">CSS and JavaScript</p>


13) The most commonly used way to apply CSS to an HTML page is by using classes. With JavaScript, the class for every element can be accessed with the className property. The following code implements the preceding phrase with the class approach:


<script language="JavaScript" type="text/javascript">
function makeBold() {
document.getElementById("para").className = "strong";
window.setTimeout("makeLighter();", 1000);
}

function makeLighter() {
document.getElementById("para").className = "weak";
window.setTimeout("makeBold();", 1000);
}

window.onload = makeBold;
</script>
<style type="text/css">
.strong { font-weight: bold; }
.weak { font-weight: lighter; }
</style>
<p id="para">CSS and JavaScript</p>


14) Removing Elements

The removeChild() method that every node has can be used to eliminate a node from the DOM tree. Note that you have to call this method from the parent element of the node to delete, and to provide the node as a parameter. The following sample shows a list and removes the last item every time the button is clicked;


<script language="JavaScript" type="text/javascript">
function removeItem() {
var list = document.getElementById("list");
if (list.childNodes.length > 0) {
list.removeChild(list.lastChild);
}
}
</script>
<ol id="list"><li>Item</li><li>Item</li><li>Item</li><li>Item</li></ol>
<input type="button" onclick="removeItem();" value="Remove item" />



The disadvantage of this approach is that the new element is always appended to the end of the children list. To mitigate this effect, the insertBefore() method allows inserting a new node before any other node (so you can insert it anywhere but at the end of the listyou still have appendChild() for this). As in parameters, you provide the new node first, then the new sibling.

15) Replacing Elements

If you remove a node and then insert another one at the same place, the replaceChild() method saves you a bit of coding. You provide the new and the old node, and JavaScript does the rest for you. Remember that you have to call this method from the parent element of the old and the new node!


<script language="JavaScript" type="text/javascript">
var nr = 1;
function addItem() {
var list = document.getElementById("list");
var newNode = document.createElement("li");
nr++;
var newTextNode = document.createTextNode("Item " + nr);
newNode.appendChild(newTextNode);
list.replaceChild(newNode, list.firstChild);
}
</script>
<ul id="list"><li>Item 1</li></ul>
<input type="button" onclick="addItem();" value="Replace item" />


16) Moving Elements

A rather rare, but still used, DHTML scenario is not only positioning an element, but also moving and therefore animating an element. To do so, window.setTimeout() and window.setInterval() come in handy. The following code animates an ad banner diagonally over the page. The only potential issue is how to animate the position. For the Internet Explorer properties (posLeft, posTop), just adding a value suffices. For left and top, you first have to determine the old position and then add a value to it. The JavaScript function parseInt() exTRacts the numeric content from a string like "123px". However, parseInt() returns NaN if no value is found in left or top. Therefore, the following helper function takes care of this situation; in this case, 0 is returned instead:


<script language="JavaScript" type="text/javascript">
var nr = 0;
var id = null;
function myParseInt(s) {
var ret = parseInt(s);
return (isNaN(ret) ? 0 : ret);
}
function animate() {
nr++;
if (nr > 50) {
window.clearInterval(id);
document.getElementById("element").style.visibility = "hidden";
} else {
var el = document.getElementById("element");
el.style.left = (myParseInt(el.style.left) + 5) + "px";
el.style.posLeft += 5;
el.style.top = (myParseInt(el.style.top) + 5) + "px";
el.style.posTop += 5;
}
}
window.onload = function() {
id = window.setInterval("animate();", 100);
};
</script>
<h1>My Portal</h1>
<p>Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text. </p>
<div id="element" style="position: absolute; background-color: #eee; border: 1px solid">
</div>



17) Extending Built-In JavaScript Objects

The prototype property can also be used to extend built-in JavaScript classes. In the following code, a function, isLeapYear(), is implemented that determines whether the return value of getFullYear() is a leap year. Note that the getFullYear() method is not implemented; using the prototype property, however, isLeapYear() becomes a method of the Date object and thus also has access to Date.getFullYear().


<script language="JavaScript" type="text/javascript">
function isLeapYear() {
var y = this.getFullYear();
return (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0));
}
Date.prototype.isLeapYear = isLeapYear;

var d = new Date();
window.alert(d.isLeapYear());
</script>




About the Author

Christian Wenz is a professional phrasemonger, author, trainer, and consultant with a focus on web technologies. He has written or cowritten more than four dozen books. He frequently contributes articles to renowned IT magazines and speaks at conferences around the globe. Christian contributes to several PHP packages in the PEAR repository and also maintains one Perl CPAN module. He holds a degree ("Diplom") in Computer Sciences from Technical University of Munich and lives and works in Munich, Germany. He also is Europe's very first Zend Certified Professional and founding principal at the PHP Security Consortium.

2 comments:

Anonymous said...

Hi Prashant,
Great going. Appreciate you sharing your learnings. Curious question, how do you manage to read so many books :-)

cheers,
-Sapien

JP said...

Sapien,

Thanks for your comments.

Currently i am not having much day job work and i am in maintenence phase of the project as recently our project went live.Hence i am utlizing time in this way.

Thanks
Prashant