Link:http://net.tutsplus.com/tutorials/javascript-ajax/javascript-and-the-dom-series-lesson-1/
Hello and welcome to the first part of what will hopefully be an extensive series covering core aspects of the JavaScript programming language and the DOM API.
While frameworks such as jQuery, Prototype and MooTools are great ways of suppressing browser bugs and speeding up development, it’s important to know and understand the underlying technologies. This series intends to tell you what you need to know about JavaScript and the Document Object Model (DOM). Even if you swear by a particular library this will still benefit you – knowing how something works under the skin can only be a good thing!
Introductions
JavaScript
JavaScript is a dynamic, loosely typed, prototype-based programming language which is used in many different environments. As well as being the prevalent client-side programming language of the web, it’s also used to write plugins for IDEs, in PDF files and as a basis for other platforms and higher abstractions.
JavaScript is based on the ECMAScript standard (ECMA-262) and was created by Brendan Eich of Netscape. It was originally called LiveScript but it was later renamed to JavaScript, probably with the sole intention of causing confusion.
Here are some of its features in a little more detail:
- Dynamic programming languages execute at runtime; they are not compiled. Because of this, JavaScript is sometimes considered a scripting language as opposed to a true programming language (obviously a misconception). When you have JavaScript within an HTML document it will be parsed as the page loads within the browser, hence at "runtime".
- Loosely typed languages do not insist upon any strong typing system. If you’ve programmed in C or Java (not the same as JavaScript) you’ll know that when declaring a variable you have to specify a type such as ‘int’ (integer). JavaScript is different in that you don’t need to specify the type.
- To perform inheritance within JavaScript you have to use something called prototypes. JavaScript does not support classes.
- JavaScript is also a functional language. It treats functions as first-class objects; this is the idea behind lambda.
Understanding the above points is not important in learning about JavaScript; it’s just a few ideas to get your brain in gear, and should help you differentiate JavaScript from other programming languages you may have experienced.
Document Object Model
The Document Object Model, normally abbreviated to DOM, is the API through which JavaScript interacts with content within a website. JavaScript and the DOM are usually seen as a single entity since JavaScript is most commonly used for this purpose (interacting with content on the web). The DOM API is used to access, traverse and manipulate HTML and XML documents.
Here’s a few noteworthy things about the DOM:
- The window object serves as the global object, you access it by just typing "window". It’s within this object that all of your JavaScript code is executed. Like all objects it has properties and methods.
- A property is a variable stored under an object. All variables created on a web-page authomatically become properties of the window object.
- A method is a function stored under an object. Since all functions are stored under (at least) the window object they can all be referred to as ‘methods’.
- The DOM creates a hierarcy corresponding to the structure of each web document. This hierarchy is made up of nodes. There are several different types of DOM nodes, the most important are ‘Element’, ‘Text’ and ‘Document’.
- An ‘Element’ node represents an element within a page. So if you have a paragraph element (‘<p>’) then it can be accessed through the DOM as a node.
- A ‘Text’ node represents all text (within elements) within a page. So if your paragraph has a bit of text in it can be directly accessed through the DOM.
- The ‘Document’ node represents the entire document. (it’s the root-node of the DOM hierarchy/tree).
- Also note that element attributes are DOM nodes themselves.
- Each layout engine has a slightly different implementation of the DOM standard. For example, theFirefox web browser, which uses the Gecko layout engine, has quite a good implementation (although, not entirely inline with the W3C specification) but Internet Explorer, which uses the Tridentlayout engine is known for it’s buggy and incomplete implementation; a cause of much anguish within the web development community!
Download Firebug
If you’re using Firefox and you don’t already have the Firebug addon I recomend you download and install it now. It’s a very useful tool for getting a decent picture of the entire document structure.
JavaScript on the Web
The Script Element
When you want to use JavaScript on a website it has to be included within a SCRIPT element:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title>JavaScript!</title>
- </head>
- <body>
- <script type="text/javascript">
- // <![CDATA[
- // ]]>
- </script>
- </body>
- </html>
As you can see we’ve got a SCRIPT element at the bottom of our document. The TYPE attribute should strictly be set to ‘application/javascript’ but to no surprise that doesn’t work in Internet Explorer so we’re stuck with either ‘text/javascript’ or no TYPE attribute at all. If you care about validation then the former suggestion will probably suit you.
You’ll also have noticed that within that SCRIPT element we have a couple of commented-out lines. These inform XHTML-supporting browsers that the content of the SCRIPT element is ‘character data‘ and should not be interpreted as XHTML markup. It’s only really necessary if you plan on using either the ‘<’ or ‘>’ characters in your JavaScript code. Obviously you can forget about all this if you’re using plain HTML.
The Defer Attribute
Any JavaScript we put inside that SCRIPT element will run as the page loads. The only exception is when a SCRIPT element has a ‘defer’ attribute. By default, when a browser meets a SCRIPT element, it will stop and run the code, then it will carry on parsing the document. The DEFER attribute informs the browser that the code contains no document-altering code and so can be run later. The only problem with this is that it only works in IE, so it’s probably best to avoid this attribute.
Linking to External Scripts
If you want to link to an external script file then simply add an SRC attribute to your SCRIPT element corresponding to its location. It’s normally a better idea to have seperate script files than to write code inline as it means the browser can cache the file. Plus you don’t need to worry about any of that CDATA nonsense:
- <script type="text/javascript" src="my-script.js"></script>
JavaScript essentials
Before we continue with the DOM it’s a good idea to have a basic grasp of some JavaScript essentials. If you have trouble understanding some of these, don’t worry – you’ll eventually pick them up!
In JavaScript you can have different types of values. There are Numbers, Strings, Booleans, Objects, Undefined and Null:
Single-line comments are written using two forward slashes (//), all remaining text on that line is assumed to be a comment by the parser. Multi-line comments are signified using ‘/*’ and ‘*/’ to finish the comment.
Numbers
In JavaScript all numbers are represented as floating-point values. When defining a number variable remember not to wrap it in any quotes.
- // Note: ALWAYS use 'var' to declare a variable:
- var leftSide = 100;
- var topSide = 50;
- var areaOfRectangle = leftSide * topSide; // = 5000
Strings
Any string you define is taken literally, JavaScript will not process it. A string is a sequence of Unicode characters and should be wrapped in a matching pair of either single or double quotes.
- var firstPart = 'Hello';
- var secondPart = 'World!';
- var allOfIt = firstPart + ' ' + secondPart; // Hello World!
- // The + sign is used as the string-concatenation operator
- // (it's also used for numerical addition)
Booleans
Boolean types are useful when you want to evaluate a condition – to see if it meets a specified criteria. There are only two possible Boolean values: true and false. Any comparison, using logical operators, will result in a Boolean.
- 5 === (3 + 2); // = true
- // You can assign Boolean values to variables:
- var veryTired = true;
- // You can test for it like this:
- if (veryTired) {
- // Sleep
- }
The ‘===’ you see above is a comparison operator, we’ll cover them later.
Functions
A Function is a specialised Object:
- // Using the function operator to create a new function:
- function myFunctionName(arg1, arg2) {
- // Function code goes here.
- }
- // If you omit the function's name then
- // you're creating an "anonymous function":
- function(arg1, arg2) {
- // Function code goes here.
- }
- // Running a function is simply a case of referencing it
- // and then adding a parenthesis (with arguments):
- myFunctionName(); // No arguments
- myFunctionName('foo', 'bar'); // with arguments
- // You can also run a function without assinging
- // it to a variable:
- (function(){
- // This is known as a self-invoking anonymous function
- })();
Arrays
An Array is also a specialised object and can contain any number of data values. To access data values within an array you must use a number, referred to as the ‘index’ of the item you’re trying to retrieve:
- // 2 different ways of declaring a new array,
- // Literal:
- var fruit = ['apple', 'lemon', 'banana'];
- // Using the Array constructor:
- var fruit = new Array('apple', 'lemon', 'banana');
- fruit[0]; // Access the 1st item of the array (apple)
- fruit[1]; // Access the 2nd item of the array (lemon)
- fruit[2]; // Access the 3rd item of the array (banana)
Objects
An Object is a collection of named values (key – value pairs). It’s similar to an array, the only difference is that you can specify a name for each data value.
- // 2 different ways of declaring a new Object,
- // Literal (curly braces):
- var profile = {
- name: 'Bob',
- age: 99,
- job: 'Freelance Hitman'
- };
- // Using the Object constructor:
- var profile = new Object();
- profile.name = 'Bob';
- profile.age = 99;
- profile.job = 'Freelance Hitman';
If/Else Statement
One of the most common constructs in JavaScript is the ‘IF’ / ‘ELSE’ statement. It goes something like this:
- var legalDrinkingAge = 21;
- var yourAge = 29;
- if ( yourAge >= legalDrinkingAge ) {
- // We can use 'alert' to notify the user:
- alert('You can drink.');
- } else {
- alert('Sorry, you cannot drink.');
- }
JavaScript Operators:
Instead of listing them all out here I suggest you visit the MDC article on Operators. It explains them in a lot of detail. I’ve setup a few examples to give you an idea of how some of the operators are used below:
- // additioa/substraction/multiply/divide
- var someMaths = 2 + 3 + 4 - 10 * 100 / 2;
- // Equality
- if ( 2 == (5 - 3 ) { /* Do stuff */ } // == checks for eqaulity
- // Inequality
- if ( 2 != (5 - 3 ) { /* Do stuff */ }
- // Strict Equality operators:
- // (I suggest using these)
- 2 === 2 // Instead of 2 == 2
- 2 !== 3 // Instead of 2 != 3
- // Assignment:
- var numberOfFruit = 9;
- numberOfFruit -= 2; // Same as "numberOfFruit = numberOfFruit - 2"
- numberOfFruit += 2; // Same as "numberOfFruit = numberOfFruit + 2"
Looping
Looping is useful when you need to go through all items in an array or all members of an object. The most common way to loop in JavaScript is by using either the FOR or WHILE statement.
- var envatoTutSites = ['NETTUTS','PSDTUTS','AUDIOTUTS','AETUTS','VECTORTUTS'];
- // WHILE loop
- var counter = 0;
- var lengthOfArray = envatoTutSites.length;
- while (counter < lengthOfArray) {
- alert(envatoTutSites[counter]);
- counter++; // Same as counter += 1;
- }
- // FOR loop
- // (The i stands for "iterator" - you could name it anything)
- for (var i = 0, length = envatoTutSites.length; i < length; i++) {
- alert(envatoTutSites[i]);
- }
Back to the DOM
Accessing DOM nodes
Let’s assume we have a basic XHTML document containing a paragraph and an unordered list:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title>JavaScript!</title>
- </head>
- <body>
- <p id="intro">My first paragraph...</p>
- <ul>
- <li>List item 1</li>
- <li>List item 1</li>
- <li>List item 1</li>
- <li>List item 1</li>
- <li>List item 1</li>
- </ul>
- <script type="text/javascript">
- // <![CDATA[
- // ]]>
- </script>
- </body>
- </html>
In this first example we’re going to access our paragraph by using the ‘getElementById’ DOM method:
(This code goes within the SCRIPT element in the above template).
- var introParagraph = document.getElementById('intro');
- // We now have a reference to the DOM node. This DOM
- // node represents the intro paragraph.
The variable ‘introParagraph’ is now a reference to the DOM node. We can do a number of things with this node, – we can query its content and attributes, and can manipulate any aspect of it. We can remove it, clone it or move it to other parts of the DOM tree.
Anything which is present within a document we can access using JavaScript and the DOM API. So, we might want to access the unordered list in a similar fashion, the only problem is that it doesn’t have an ID. You could give it an ID and then use the same method as above or we could access it using ‘getElementsByTagName’:
- var allUnorderedLists = document.getElementsByTagName('ul');
- // 'getElementsByTagName' returns a live node collection/list
- // - It's very similar to an array with a few slight differences.
getElementsByTagName
The ‘getElementsByTagName’ method returns a live node collection/list. It’s similar to an array in that it has a length property. One important thing to note is these collections are "live" – if you add a new element to the DOM then the collection will update itself. Since it’s an array-like object we can access each node via an index, from 0 to the total length of the collection (minus 1):
- // Access single unordered list: [0] index
- var unorderedList = document.getElementsByTagName('ul')[0];
- // Create Node list of all list items within the UL:
- var allListItems = unorderedList.getElementsByTagName('li');
- // Now, we can loop through each list item using a FOR loop:
- for (var i = 0, length = allListItems.length; i < length; i++) {
- // Extract text node within and alert its content:
- alert( allListItems[i].firstChild.data );
- }
Traversing the DOM
The term "traverse" is used to describe the action of travelling through the DOM, finding nodes. The DOM API gives us plenty of node properties which we can use to move up and down through all the nodes within a document.
These properties are inherent of all nodes and enable you to access related/close nodes:
- Node.childNodes: You can use this to access all direct child nodes of a single element. It will be an array-like object, which you can loop through. Nodes within this array will include all the different node types including text nodes and other element nodes.
- Node.firstChild: This is the same as accessing the first item in the ‘childNodes’ array (‘Element.childNodes[0]‘). It’s just a shortcut.
- Node.lastChild: This is the same as accessing the last item in the ‘childNodes’ array (‘Element.childNodes[Element.childNodes.length-1]‘). It’s just a shortcut.
- Node.parentNode: This gives you access to the parent node of your current node. There will only ever be one parent node. In order to access the grandparent you would simply use ‘Node.parentNode.parentNode’ etc.
- Node.nextSibling: This gives you access to the next node on the same level within the DOM tree.
- Node.previousSibling: This gives you access to the last node on the same level within the DOM tree.
So, as you can see, traversing the DOM is incredibly easy, it’s just a case of knowing the property names.
One thing to note about the above graphic: the list items can only be retrieved in that fashion if there is no whitespace between them. Because you can have text nodes and element nodes in a document the space in between the ‘<ul>’ and the first ‘<li>’ actually counts as a node itself. Similarily the unordered list is not actually the paragraph’s next sibling – since it’s on a new line there is space between the two elements – hence, another node! Normally, what you’d do in this situation would be to loop through the ‘childNodes’ array and test the ‘nodeType’. A ‘nodeType’ of 1 means it’s an element, 2 means it’s an attribute, 3 means it’s a text node. You can see a full list here: https://developer.mozilla.org/En/DOM/Node.nodeType.
That’s all it is!
This is how all major JavaScript libraries work behind the scenes; using native DOM methods and properties to give you access to these elements through a nicely polished abstraction. What seperates you from the framework diehards is that you now have some idea of how to survive without a framework (if you didn’t already)!
No comments:
Post a Comment