I recently read "proficient in JavaScript". The author is the father of jquery. I believe many garden friends who have studied JavaScript have read this book and it is worth studying. After reading the Document Object Model and the events, I still feel very beneficial. Although I have known Dom and event before, I should say that I have understood it more deeply this time.
When traversing the Dom, you must note that the node pointer in the DOM (such as ELEM. parentnode, ELEM. firstchild, ELEM. nextsibling, etc.) can point to element nodes or text nodes, which may cause some confusion, such as: <Div id = "content">
<P> This is main content area </P>
</Div>
How do you locate the P element in the div? The document may be taken for granted. getelementbyid ("content "). firstchild. Unfortunately, it is "\ n" (the node nodetype of a text type is 3). You must use document. getelementbyid ("content "). firstchild. nextsibling is not difficult and concise enough to facilitate reading. The book encapsulates some simple Dom traversal methods.
Function Prev (ELEM ){
Do {
ELEM = ELEM. previussibling;
} While (ELEM & ELEM. nodetype! = 1); // If nodetype is set to 1, it indicates that the node is an element, for example, <p>, <A>
Return ELEM;
}
Function next (ELEM ){
Do {
ELEM = ELEM. nextsibling;
} While (ELEM & ELEM. nodetype! = 1 );
Return ELEM;
}
Function first (ELEM ){
ELEM = ELEM. firstchild;
Return ELEM & ELEM. nodetype! = 1?
Next (ELEM): ELEM;
}
Function last (ELEM ){
ELEM = ELEM. lastchild;
Return ELEM & ELEM. nodetype! = 1?
Prev (ELEM): ELEM;
}
Function parent (ELEM, num ){
Num = num | 1; // If num is not provided, the default value is 1, indicating the number of nested layers of elements.
For (VAR I = 0; I <num; I ++ ){
If (ELEM! = NULL) ELEM = ELEM. parentnode;
}
Return ELEM;
}
With these simple functions, we can traverse the DOM like this: First (document. getelementbyid ("content"); this seems much better, but if you change the function call to this form, it should be more in line with the habit: document. body. first (). next (), we can achieve this by extending the htmlelement (unfortunately, the damn ie cannot directly access the htmlelement object ).
Htmlelement. Prototype. Next = function (){
VaR ELEM = this;
Do {
ELEM = ELEM. nextsibling;
} While (ELEM & ELEM. nodetype! = 1 );
Return ELEM;
}
The frequently used getelementbyid and getelementsbytagname methods are also mentioned in the book, and simple encapsulation is provided.
Function tag (name, ELEM ){
// If ELEM is not provided, the default document
Return (ELEM | document). getelementsbytagname (name );
}
Function ID (elemid ){
Return document. getelementbyid (elemid );
}
The following focuses on waiting for the HTML Dom to load, which is very important. The author also describes the order of webpage loading:
1. html parsed by the browser
2. External JS and CSS are loaded
3. When JS is parsed in the document, JS is executed
4. html Dom constructed
5. Images and external content are loaded
6. Page Loading completed
Obviously, there is a problem here. js that is earlier than the document or JS that is loaded externally. If the HTML Dom is not fully constructed, the access to Dom by these JS will certainly fail, the author provides several solutions to this problem.
1. Use the window. onload event. Here, I changed the addevent method in the original article (the more complicated one written by Dean Edwards)
Function addevent (OBJ, event, eventhandler ){
If (obj. addeventlistener) {// non-iebrowser W3C Standard
OBJ. addeventlistener (event, eventhandler, false );
} Else if (obj. attachevent) {// write it here, and I think IE is damn...
Event = "on" + event;
OBJ. attachevent (event, eventhandler );
}
}
Then we can: addevent (window, "LOAD", function (){
First (ID ("content"). style. Background = 'blue ';
});
This method is very common and feels good.
2. Execute JSCodeTo the last position of the DOM
<Body>
<H1> testing Dom loading
<! -- Lots of HTML goes here -->
<SCRIPT type = "text/JavaScript"> Init (); // The init method is written in
</Body>
3. This method is a function written by the author to confirm the completion of Dom load. It is mainly used to monitor the status of Dom documents in real time. The Code is as follows:
// Check whether the Dom can be traversed
Function isdomready (){
// If we have confirmed that the page loading is complete, ignore
If (domready. Done) return false;
// Check whether some functions and elements can be accessed
If (Document & document. getelementsbytagname & document. getelementbyid & document. Body ){
// If everything is ready, we will stop the check
Clearinterval (domready. Timer );
Domready. Timer = NULL;
// Execute all functions in the queue
For (VAR I = 0; I <domready. Ready. length; I ++ ){
Domready. Ready [I] ();
}
// Remember, we have done it now.
Domready. Ready = NULL;
Domready. Done = true;
}
}
Function domready (f ){
// If the Dom has been loaded, execute the function immediately.
If (domready. Done) return F ();
// If we have added a function
If (domready. Timer ){
// Add it to the execution list
Domready. Ready. Push (f );
} Else {
// Append an event to the page after loading
Addevent (window, 'load', isdomready );
// Initialize the execution function list
Domready. Ready = [f];
// Check whether the Dom has been loaded as soon as possible
Domready. Timer = setinterval (isdomready, 13 );
}
}
The author introduces some methods to find elements. There is a finding elements by class name, which is implemented as follows:
Function hasclass (name, type ){
VaR r = [];
// Locate the class name (multiple classes are allowed)
VaR Re = new Regexp ("(^ | \ s)" + name + "(\ s | $ )");
VaR E = Document. getelementsbytagname (type | "*");
For (var j = 0; j <E. length; j ++ ){
// If this element has this class, add it to the result set.
If (Re. Test (E [J]. classname) R. Push (E [J]);
}
Return R;
}
We will go here today and continue to review tomorrow .......