2.1 document node overview
The HTMLDocument constructor (which inherits from document) when instantiated represents specifically aDOCUMENT_NODE (i.e. window.document) in the DOM. To verify this we can simply ask which constructor was used in the creation of the document node object.
live code: http://jsfiddle.net/domenlightenment/qRAzL
<!DOCTYPE html>
<html lang="en">
<body>
<script>
console.log(window.document.constructor); //logs function HTMLDocument() { [native code] }
console.log(window.document.nodeType); //logs 9, which is a numeric key mapping to DOCUMENT_NODE
</script>
</body>
</html>
The code above concludes that the HTMLDocument constructor function constructs the window.document node object and that this node is a DOCUMENT_NODE object.
Notes
Both Document and HTMLDocument constructors are typically instantiated by the browser when you load an HTML document. However, using document.implementation.createHTMLDocument() its possible to create your own HTML document outside of the one currently loaded into the browser. In addtion to createHTMLDocument() its also possible to create a document object which has yet to be setup as an HTML document using createDocument(). Typically the use of theses methods are associated with programatically providing an HTML document to an iframe.
2.2 HTMLDocument properties and methods (including inherited)
To get accurate information pertaining to the available properties and methods on an HTMLDocument node its best to ignore the specification and to ask the browser what is available. Examine the arrays created in the code below detailing the properties and methods available from an HTMLDocument node (a.k.a. window.document) object.
live code: http://jsfiddle.net/domenlightenment/jprPe
<!DOCTYPE html>
<html lang="en">
<body>
<script>
//document own properties
console.log(Object.keys(document).sort());
//document own properties & inherited properties
var documentPropertiesIncludeInherited = [];
for(var p in document){
documentPropertiesIncludeInherited.push(p);
}
console.log(documentPropertiesIncludeInherited.sort());
//documment inherited properties only
var documentPropertiesOnlyInherited = [];
for(var p in document){
if(
!document.hasOwnProperty(p)){documentPropertiesOnlyInherited.push(p);
}
}
console.log(documentPropertiesOnlyInherited.sort());
</script>
</body>
</html>
The available properties are many even if the inherited properties were not considered. Below I"ve hand pick a list of noteworthy properties and methods for the context of this chapter.
- doctype
- documentElement
- implementation.
- activeElement
- body
- head
- title
- lastModified
- referrer
- URL
- defaultview
- compatMode
- ownerDocument
- hasFocus()
Notes
The HTMLDocument node object is used to access (typically inherit) a great deal of the methods and properties available for working with the DOM (i.e. document.querySelectorAll()). You will be seeing many of these properties not discussed in this chapter discussed in the appropriate chapter"s following this chapter.
2.3 Getting general HTML document information (title, url, referrer, lastModified, compatMode)
The document object provides access to some general information about the HTML document/DOM being loaded. In the code below I use the document.title, document.URL, document.referrer, document.lastModified, and document.compatMode properties to gain some general information about the document. Based on the property name the returned values should be obvious.
live code: http://jsfiddle.net/domenlightenment/pX8Le
<!DOCTYPE html>
<html lang="en">
<body>
<script>
var d = document;
console.log("title = " +d.title);
console.log("url = " +d.URL);
console.log("referrer = " +d.referrer);
console.log("lastModified = " +d.lastModified);
//logs either BackCompat (Quirks Mode) or CSS1Compat (Strict Mode)
console.log("compatibility mode = " +d.compatMode);
</script>
</body>
</html>
2.4 document child nodes
Document nodes can contain one DocumentType node object and one Element node object. This should not be a surprise since HTML documents typically contain only one doctype (e.g. <!DOCTYPE html>
) and one element (e.g. <html lang="en">
). Thus if you ask for the children (e.g. document.childNodes) of the Document object you will get an array containing at the very least the documents doctype/DTD and <html lang="en">
element. The code below showcases that window.document is a type of node object (i.e Document) with child nodes.
live code: http://jsfiddle.net/domenlightenment/UasKc
<!DOCTYPE html>
<html lang="en">
<body>
<script>
//This is the doctype/DTD
console.log(document.childNodes[0].nodeType); //logs 10, which is a numeric key mapping to DOCUMENT_TYPE_NODE
//This is the <html> element
console.log(document.childNodes[1].nodeType); //logs 1, which is a numeric key mapping to ELEMENT_TYPE_NODE
</script>
</body>
</html>
Notes
Don"t confuse the window.document object created from HTMLDocument constructor with the Document object. Just rememberwindow.document is the starting point for the DOM interface. That is why document.childNodes contains child nodes.
If a comment node (not discussed in this book) is made outside of the <html lang="en">
element then it will become a child node of the window.document. However having comment nodes outside of the <html>
element can cause some buggy results in IE and also is a violation of the DOM specification.
2.5 document provides shortcuts to <!DOCTYPE>
, <html lang="en">
, <head>
, and <body>
Using the properties listed below we can get a shortcut reference to the following nodes:
- document.doctype refers to
<!DOCTYPE>
- document.documentElement refers to
<html lang="en">
- document.head refers to
<head>
- document.body refers to
<body>
This is demonstrated in the code below.
live code: http://jsfiddle.net/domenlightenment/XsSTM
<!DOCTYPE html>
<html lang="en">
<body>
<script>
console.log(document.doctype); // logs DocumentType {nodeType=10, ownerDocument=document, ...}
console.log(document.documentElement); // logs <html lang="en">
console.log(document.head); // logs <head>
console.log(document.body); // logs <body>
</script>
</body>
</html>
Notes
The doctype or DTD is a nodeType of 10 or DOCUMENT_TYPE_NODE and should not be confused with the DOCUMENT_NODE (akawindow.document constructed from HTMLDocument()). The doctype is constructed from the DocumentType() constructor.
In Safari, Chrome, and Opera the document.doctype does not appear in the document.childNodes list.
2.6 Detecting DOM specifications/features usingdocument.implementation.hasFeature()
Its possible using document.implementation.hasFeature() to ask (boolean) the current document what feature and level the browser has implemented/supports. For example we can ask if the browser has implemented the core DOM level 3 specification by passing the name of the feature and the version to the hasFeature()method. In the code below I ask if the browser has implemented the Core 2.0 & 3.0 specification.
live code: http://jsfiddle.net/domenlightenment/TYYZ6
<!DOCTYPE html>
<html lang="en">
<body>
<script>
console.log(document.implementation.hasFeature("Core","2.0"));
console.log(document.implementation.hasFeature("Core","3.0"));
</script>
</body>
</html>
The following table defines the features (spec calls these modules) and versions that you can pass thehasFeature() method.
Feature | Supported Versions |
---|---|
Core | 1.0, 2.0, 3.0 |
XML | 1.0, 2.0, 3.0 |
HTML | 1.0, 2.0 |
Views | 2.0 |
StyleSheets | 2.0 |
CSS | 2.0 |
CSS2 | 2.0 |
Events | 2.0, 3.0 |
UIEvents | 2.0, 3.0 |
MouseEvents | 2.0, 3.0 |
MutationEvents | 2.0, 3.0 |
HTMLEvents | 2.0 |
Range | 2.0 |
Traversal | 2.0 |
LS (Loading and saving between files and DOM trees synchronously) | 3.0 |
LS-Asnc (Loading and saving between files and DOM trees asynchronously) | 3.0 |
Validation | 3.0 |
Notes
Don"t trust hasFeature() alone you should also use capability detection in addition to hasFeature().
Using the isSupported method implementation information can be gathered for a specific/selected node only (i.e.element.isSupported(feature,version).
You can determince online what a user agent supports by visiting http://www.w3.org/2003/02/06-dom-support.html. Here you will find a table indicating what the browser loading the url claims to implement.
2.7 Get a reference to the focus/active node in the document
Using the document.activeElement we can quickly get a reference to the node in the document that is focused/active. In the code below, on page load, I am setting the focus of the document to the <textarea>
node and then gaining a reference to that node using the activeElement property.
live code: http://jsfiddle.net/domenlightenment/N9npb
<!DOCTYPE html>
<html lang="en">
<body>
<textarea></textarea>
<script>
//set focus to <textarea>
document.querySelector("textarea").focus();
//get reference to element that is focused/active in the document
console.log(document.activeElement); //logs <textarea>
</script>
</body>
</html>
Notes
The focused/active element returns elements that have the ability to be focused. If you visit a web page in a browser and start hitting the tab key you will see focus shifting from element to element in that page that can get focused. Don"t confuse the selection of nodes (highlight sections of the HTML page with mouse) with elements that get focus for the purpose of inputting something with keystrokes, spacebar, or mouse.
2.8 Determing if the document or any node inside of the document has focus
Using the document.hasFocus() method its possible to know if the user currently is focused on the window that has the HTML document loaded. In the code below you see that if we execute the code and then focus another window, tabe, or application all together the getFocus() will return false.
live code: http://jsfiddle.net/domenlightenment/JkE3d
<!DOCTYPE html>
<html lang="en">
<body>
<script>
//If you keep focus on the window/tab that has the document loaded its true. If not it"s false.
setTimeout(function(){console.log(document.hasFocus())},5000);
</script>
</body>
</html>
2.9 document.defaultview is a shortcut to the head/global object
You should be aware that the defaultView property is a shortcut to the JavaScript head object or what some refer to as the global object. The head object in a web browser is the window object and defaultView will point to this object in a JavaScript browser enviroment. The code below demonstrates the value of defaultView in a browser.
live code: http://jsfiddle.net/domenlightenment/QqK6Q
<!DOCTYPE html>
<html lang="en">
<body>
<script>
console.log(document.defaultView) //reference, head JS object. Would be window object in a browser.
</script>
</body>
</html>
If you are dealing with a DOM that is headless or an JavaScript enviroment that is not running in a web browser (i.e. node.js) this property can get you access to the head object scope.
2.10 Getting a reference to the Document from an element usingownerDocument
The ownerDocument property when called on a node returns a reference to the Document the node is contained within. In the code below I get a reference to the Document of the <body>
in the HTML document and theDocument node for the <body>
element contained inside of the iframe.
live code: N/A
<!DOCTYPE html>
<html lang="en">
<body>
<iframe src="http://someFileServedFromServerOnSameDomain.html"></iframe>
<script>
//get the window.document that the <body> is contained within
console.log(document.body.ownerElement);
//get the window.document the <body> inside of the iframe is contained within
console.log(window.frames[0].document.body.ownerElement);
</script>
</body>
</html>
If ownerDocument is called on the Document node the value returned is null.