|Language:||English, Spanish, French|
|Distribution:||Free* [*Registration needed]|
I read all of it in one night and I think it is one of the best references I've read in the last year and has definitely made me a better front end developer. Awesome book, really hit the nail on the head for me. I was looking for something that explained the DOM and this small but precise book did it for me.
One person found this helpful. This book is excellent for anyone seeking to understand how the DOM works. As Bill and Ted would say, "Most excellent dude! Kindle Edition Verified download. Wow, I didn't realize there was so much to the DOM.
I thought I was an expert until I read this book and discovered that I could do so much more. Useful material at a reasonable price. Short and to the point. Helped me. Very good book to know about HTML noodes. A lot of simple examples which shows how it works. Good for beginners and for advanced technics. Good book. See all 14 reviews. site Giveaway allows you to run promotional giveaways in order to create buzz, reward your audience, and attract new followers and customers.
CSS Secrets: Lea Verou.
Using the childNodes property produces an array like list i. NodeList of the immediate child nodes. Be aware childNodes contains not only Element nodes but also all other node types e.
In the code below I use the. From a node reference i. In the code example below we examine the Node properties providing DOM traversal functionality. If you have been around the DOM much then it should be no surprise that traversing the DOM includes not just traversing element nodes but also text and comment nodes. I believe the last code example makes this clear, and this is not exactly ideal.
Using the following properties we can traverse the DOM ignoring text and comment nodes. The childElementCount is not mentioned but you should be aware of its avaliablity for calculating the number of child elements a node contains. Its possible to know if a node is contained inside of another node by using the contains Node method. If you need more robust information about the position of a node in the DOM tree in regards to the nodes around it you can use the compareDocumentPosition Node method.
Basically this method gives you the ability to request information about a selected node relative to the node passed in.
The information that you get back is a number that corresponds to the following information. For example when a node both contains 16 and precedes 4 the returned value from compareDocumentPosition will be According to the DOM 3 specification two nodes are equal if and only if the following conditions are satisfied:.
Calling the. Below I exhibt a case of an two equal nodes and two non-identical nodes. This will tell us if they are identical but no equal. To verify this we can simply ask which constructor was used in the creation of the document node object. However, using document. Typically the use of theses methods are associated with programatically providing an HTML document to an iframe. 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. 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. You will be seeing many of these properties not discussed in this chapter discussed in the appropriate chapter's following this chapter. In the code below I use the document.
URL , document. Based on the property name the returned values should be obvious. 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. Thus if you ask for the children e.
The code below showcases that window.
Don't confuse the window. Just remember window. That is why document. The doctype is constructed from the DocumentType constructor.
In Safari, Chrome, and Opera the document. Its possible using document. 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. The following table defines the features spec calls these modules and versions that you can pass the hasFeature method.
Don't trust hasFeature alone you should also use capability detection in addition to hasFeature. You can determince online what a user agent supports by visiting http: Here you will find a table indicating what the browser loading the url claims to implement.
Using the document. 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.
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.
Examine the arrays created in the code below detailing the properties and methods available from HTML element nodes. Below I've hand pick a list of note worthy properties and methods inherited as well for the context of this chapter. Element nodes are instantiated for us when a browser interputs an HTML document and a corresponding DOM is built based on the contents of the document.
After this fact, its also possible to programaticlly create Element nodes using createElement. The value passed to the createElement method is a string that specifices the type of element aka tagName to be created. This value passed to createElement is changed to a lower-case string before the element is created. Using the tagName property we can access the name of an element. The tagName property returns the same value that using nodeName would return. Both return the value in uppercase regardless of the case in the source HTML document.
Using the attributes property inherited by element nodes from Node we can get a collection of the Attr nodes that an element currently has defined. The list returned is a NameNodeMap.
Below I loop over the attributes collection exposing each Attr node object contained in the collection. The array returned from accessing the attributes property should be consider live. Meaning that its contents can be changed at anytime. Operating on attributes with these methods should be secondary to using getAttribute , setAttribute , hasAttribute , removeAttribute. Its this authors opinion that dealing with Attr nodes is messy.
The only merit in using the attributes is found only in its funcitonaly for returning a list of live attributes. The attributes property is an array like collection and has a read only length property.
Boolean attributres e. The most consistent way to get, set, or remove an elements attribute value is to use the getAttribute , setAttribute , and removeAttribute method.
In the code below I demonstrate each of these methods for managing element attributes. Use removeAttribute instead of setting the attribute value to null or '' using setAttribute. Some element attributes are available from element nodes as object properties i.
This author recommends avoiding these properties and using the remove, set, and get attribute methods. The best way to determine i. This method will return true if the element contains the attribute even if the attribute has no value.
For example using hasAttribute we can get a boolean response for boolean attributes. In the code example below we check to see if a checkbox is checked. Using the classList property available on element nodes we can access a list i. DOMTokenList of class attribute values that is much easier to work with than a space-delimited string value returned from the className property. In the code below I contrast the use of classList with className. Given the classList is an array like collection it has a read only length property.
IE9 does not support classList. Support will land in IE Several polyfills are avaliable. Using the classList. In the code below I demonstrated adding and removing class values. This allows us to add a value if its missing or remove a value if its already added. In the code below I toggle the 'visible' value and the 'grow' value. Which essentially means I remove 'visible' and add 'grow' to the class attribute value.
Basically you can pass this method a CSS 3 selector e. For example, in the code example above we pass a selector that would select all the li's in CSS, but only the first one is returned. This allows for the method to limit allows for context querying its results to a specific vein of the DOM tree. If its not clear the methods used in the code example above do not select a specific element, but instead creates a list aka NodeLists of elements that you can select from. The querySelectorAll method does not return a live list of elements.
Meaning that the list created from querySelectorAll is a snap shot of the document at the time it was created and is not reflective of the document as it changes. The list is static not live. This allows for the method to limit its results to specific vein s of the DOM tree e. I did not mention the getElementsByName method as it not commonly leverage over other solutions but you should be aware of its existence for selecting form, img, frame, embed, and object elements from a document that all have the same name attribute value.
Using the children property from an element node we can get a list aka HTMLCollection of all the immediate children nodes that are element nodes. Notice that using children only gives us the immediate element nodes excluding any nodes e.
If the element has no children then children will return an empty array-like-list. HTMLCollection 's contain elements in document order, that is they are placed in the array in the order the elements appear in the DOM. HTMLCollection 's are live, which means any change to the document will be reflected dynamically in the collection.
This allows for these methods to limit its results to specific vein s of the DOM tree. Or said another, you can select a specific context in which you would like the methods to search for element nodes by invoking these methods on element node objects.
These methods not only operate on the live dom but programatic DOM structures that are created in code as well. You should be aware that there are some legacy, pre-configured arrays-like-lists, containing element nodes from an HTML document.
Below I list a couple of these not the complete list that might be handy to be aware of. Oddly document. Using the matchesSelector method we can determine if an element will match a selector string. Because it in fact does, the matchesSelector method returns true. DOM nodes are parsed and painted into visual shapes when viewing html documents in a web browser. A subset of methods and properties found in this specification provide an API to determine the geometry i.
This chapter breaks down these methods and properties. In other words, the values are live. Using the properties offsetTop and offsetLeft we can get the offset pixel value of an element node from the offsetParent.
These element node properties give us the distance in pixels from an elements outside top and left border to the inside top and left border of the offsetParent. The value of the offsetParent is determined by searching the nearest ancestor elements for an element that has a CSS position value not equal to static.
Lets verify that offsetTop and offsetLeft provide the values one might expect. Examine the following image showing what the code visually show in browser to help aid your understanding of how the offsetLeft and offsetTop values are deteremined. Using the getBoundingClientRect method we can get the position of an elements outside border edges as its painted in the browser viewport relative to the top and left edge of the viewport.
This means the left and right edge are measured from the outside border edge of an element to the left edge of the viewport. And the top and bottom edges are measured from the outside border edge of an element to the top edge of the viewport.
The image below shows the browser rendered view of the above code with some added measurement indicators to show exactly how getBoudingClientRect is calculated.
The height and width properties indicate the size of the element where the total size is derived by adding the content of the div, its padding, and borders together. The exact same size values can also be found using from the offsetHeight and offsetWidth properties.
In the code below I leverage these properties to get the same exact height and width values provided by getBoundingClientRect. The clientWidth and clientHeight properties return a total size of an element by adding together the content of the element and its padding excluding the border sizes.
In the code below I use these two properties to get the height and width of an element including padding but excluding borders. Using elementFromPoint it's possible to get a reference to the topmost element in an html document at a specific point in the document. In the code example below I simply ask what is the topmost element 50 pixels from the top and left of the viewport.
The scrollHeight and scrollWidth properties simply give you the height and width of the node being scrolled. Since we can apply, using CSS i. If you need to know the height and width of the node inside a scrollable area when the node is smaller than the viewport of the scrollable area don't use scrollHeight and scrollWidth as this will give you the size of the viewport.
If the node being scrolled is smaller than the scroll area then use clientHeight and clientWidth to determine the size of the node contained in the scrollable area. The scrollTop and scrollLeft properties are read-write properties that return the pixels to the left or top that are not currently viewable in the scrollable viewport due to scrolling. Then I get the current value of scrollTop and scrollLeft , which of course since we just set the value to will return a value of The reports the number of pixels scroll and indicates px's to the left and top are not viewable in the viewport.
If it helps just think of these properties as the pixel measurements of the content that is not shown in the viewport to the left or top. By selecting a node contained inside a node that is scrollable we can tell the selected node to scroll into view using the scrollIntoView method. By passing the scrollIntoView method a parameter of true I am telling the method to scroll to the top of the element being scrolled too.
The true parameter is however not needed as this is the default action performed by the method. If you want to scroll align to the bottom of the element pass a parameter of false to the scrollIntoView method. Notice in the code above that what is returned from the style property is a CSSStyleDeclaration object and not a string. Additionally note that only the elements inline styles i. Inline CSS styles are individually represented as a property i.
This provides the interface for us to get, set, or remove individual CSS properties on an element by simply setting an objects property value.
So you can not only set margin , but also marginTop. When a document is rendered in standards mode the unit of measure is require or it will be ignored. In quirksmode assumptions are made if not unit of measure is included. Take notice that the property name is passed to the setProperty and getPropertyValue method using the css property name including a hyphen e.
For more detailed information about the setProperty , getPropertyValue , and removeProperty as well as additional properties and methods have a look the documentation provided by Mozilla. Its possible using the cssText property of the CSSStyleDeclaration object as well as the getAttribute and setAttribute method to get, set, and remove the entire i.
If its not obvious you should note that replacing the style attribute value with a new string is the fastest way to make multiple changes to an elements style. The style property only contains the css that is defined via the style attribute. To get an elements css from the cascade i. In the code example below I demonstrate the reading of cascading styles, not just element inline styles. The getComputedStyles method returns color values in the rgb , , format regardless of how they were originally authored.
Shorthand properties are not computed for the CSSStyleDeclaration object you will have to use non-shorthand property names for property access e.
Style rules defined in a inline style sheet or external style sheet can be added or removed from an element using the class and id attribute. This is a the most common pattern for manipulating element styles. In the code below, leveraging setAttribute and classList. Using removeAttribute and classList.
Text in an HTML document is represented by instances of the Text constructor function, which produces text nodes. The code above concludes that the Text constructor function constructs the text node but keep in mind that Text inherits from CharacterData , Node , and Object.
To get accurate information pertaining to the available properties and methods on an Text 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 a text node.
Below I've hand pick a list of note worthy properties and methods for the context of this chapter. When a DOM is contstructed either by the browser or by programmatic means text nodes are created from white space as well as from text characters.
After all, whitespace is a character. In the code below the second paragraph, conaining an empty space, has a child Text node while the first paragraph does not. Don't forget that white space and text characters in the DOM are typically represented by a text node.
This of course means that carriage returns are considered text nodes. In the code below we log a carriage return highlighting the fact that this type of character is in fact a text node. The reality is if you can input the character or whitespace into an html document using a keyboard then it can potentially be interputed as a text node. Text nodes are created automatically for us when a browser interputs an HTML document and a corresponding DOM is built based on the contents of the document.
After this fact, its also possible to programatically create Text nodes using createTextNode. In the code below I create a text node and then inject that node into the live DOM tree.
Keep in mind that we can also inject text nodes into programmatically created DOM structures as well. Both of these return the text contained in a Text node. The CharacterData object that Text nodes inherits methods from provides the following methods for manipulating and extracting sub values from Text node values. Typically, immediate sibling Text nodes do not occur because DOM trees created by browsers intelligently combines text nodes, however two cases exist that make sibling text nodes possible.
The first case is rather obvious. If a text node contains an Element node e. Its best to look at a code example as this might sound more complicted than it really is.
The next case occurs when we are programatically add Text nodes to an element we created in our code. Which results in sibling Text nodes. The textContent property can be used to get all child text nodes, as well as to set the contents of a node to a specific Text node. When its used on a node to get the textual content of the node it will returned a concatenataed string of all text nodes contained with the node you call the method on. This functionality would make it very easy to extract all text nodes from an HTML document.
Notice that textContent gathers not just immediate child text nodes but all child text nodes no matter the depth of encapsulation inside of the node the method is called. When textContent is used to set the text contained within a node it will remove all child nodes first, replacing them with a single Text node. Most of the modern bowser, except Firefox, support a seeminly similiar property to textContent named innerText.
However these properties are not the same. Sibling Text nodes are typically only encountered when text is programaticly added to the DOM. To eliminate sibling Text nodes that contain no Element nodes we can use normalize. This will concatenate sibling text nodes in the DOM into a single Text node. In the code below I create sibling text, append it to the DOM, then normalize it. When splitText is called on a Text node it will alter the text node its being called on leaving the text up to the offset and return a new Text node that contains the text split off from the orginal text based on the offset.
In the code below the text node Hey Yo! Think of a DocumentFragment as an empty document template that acts just like the live DOM tree, but only lives in memory, and its child nodes can easily be manipulated in memory and then appended to the live DOM. Using a documentFragment to create node structures in memory is extrememly efficent when it comes time to inject the documentFragment into live node structures.
The follow are the differences. By passing the appendChild and insertBefore node methods a documentFragment argument the child nodes of the documentFragment are transported as children nodes to the DOM node the methods are called on. Document fragments passed as arguments to inserting node methods will insert the entire child node structure ignoring the documentFragment node itself.
Creating a DOM structure in memory using node methods can be verbose and laboring. When appending a documentFragment the nodes contained in the Fragment are moved from the Fragment to the structure you are appending too.
To leave the contents of a fragment in memory, so the nodes remain after appending, simply clone using cloneNode the documentFragment when appending. Each CSS rule e. Keep in mind that selecting the element that includes the style sheet i. In the code below styleSheets is leverage to gain access to all of the style sheets contained in the document.
The length property returns the number of stylesheets contained in the list starting at 0 index i. In the code below I access the style sheets in the HTML docment by first selecting the element used to include the style sheet and then leveraging the sheet property. To get accurate information pertaining to the available properties and methods on an CSSStyleSheet 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 a CSSStyleSheet node. In the code below we programaticlly access the details of each rule contained in the inline style sheet by accessing the CSSStyleRule object that represents the CSS rule in the style sheet.
To get accurate information pertaining to the available properties and methods on an CSSStyleRule 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 a CSSStyleRule node. Scripting the rules e. This object provides the following properties:. As previously discussed the styleSheets list provides a list of style sheets contained in a document.
CSSStyleRule objects in a specific style sheet. The code below logs a CSSRules list to the console. The insertRule and deleteRule methods provided the ability to programatically manipulate the CSS rules in a style sheet. Remeber the css rules in a style sheet are numerical index starting at 0.
So by inserting a new rule at index 1 the current rule at index 1 i. Deleting or removing a rule is as simple as calling deleteRule method on a style sheet and passing it the index of the rule in the style sheet to be deleted. Inserting and deleting rules is not a common practice given the difficulty around managing the cascaade and using a numeric indexing system to update a style sheet i. Just like the. In the code below I levereage the.
If you have a couple of script elements at the start of an html page nothing else is happening e. According to the specification defered scripts are suppose to be exectued in document order and before the DOMContentLoaded event. However, adherence to this specification among modern browsers is inconsistent.
By using defer the assummption is that document. By using this attribute, we are telling the browser not to block the construction i. DOM parsing, including downloading other assets e. What happens by using the async attribute is the files are loaded in parallel and parsed in order of download once they are fully downloaded.
Proven by the following code example:. As well, this strategy will remove a dependancy on DOM ready events that can liter a code base. The document. An event, in terms of the DOM, is either a pre-defined or custom moment in time that occurs in relationship with an element in the DOM, the document object, or the window object.
These moments are typically predetermined and programaticlly accounted for by associating functionality i. These moments can be initiated by that state of the UI e. Setting up events can be accomplished using inline attribute event handlers, property event handlers, or the addEventListener method. In the code below I'm demonstrating these three patterns for setting up an event.
The downside to using a property event handler is that only one value can be assigned to the event property at a time. Meaning, you can't add more than one propety event handler to a DOM node when assigning events as property values. The code below shows an example of this by assigning a value to the onclick property twice, the last value set is used when the event is invoked.
Additionaly, using event handlers inline or property event handlers can suffer from scoping nuances as one attempts to leverage the scope chain from the function that is invoked by the event. The addEventListener smooths out all of these issues, and will be used throughout this chapter.
Element nodes typically support inline event handlers e. The Document node supports property event handlers e. A property event handler historically has been refered to as a "DOM level 0 event". Which is rather confusing considering there is no level 0 event or level 1 event.
Addintioanlly, inline event handlers are known to be called, "HTML event handlers". In the tables below I detail the most common pre-defined events that can be attached to Element nodes, the document object, and the window object. Of course not all events are directly applicable to the node or object it can be attached too.
The event flow can be programmed to occur as a capture phase i. DOM tree trunk to branch or bubbling phase i.
DOM tree branches to trunk , or both. Once the capture phase ends the target phase starts, firing the click event on the target element itself. Next the propagation phase propagates up from the event target firing the click event until it reaches the window object i. The use of the capture phase is not all that common due to a lack of browser support for this phase.
Typically events are assumed to be inovked during the bubbling phase. In the code below I remove the capture phase from the previous code example and demostrate typically what is occuring during an event invocation. Modern browsers do support the use of the capture phase so what was once considered unreliable might just server some value today. For example, one could intercept an event before it occurs on the event target. Keep this knowledge of event capturing and bubbling at the forefront of your thoughts when you read the event delegation section of this chapter.
The event object passed to event listener functions contains a eventPhase property containing a number which indicates which phase an event is inoked in.
A value of 1 indicates the capture phase. A value of 2 indicates the target phase. And a value of 3 indicates bubbling phase. The addEventListener method used in the above code example takes three arguments. The first argument is the type of event to listen for.
Notice that the event type string does not contain the "on" prefix i. The second argument is the function to be invoked when the event occurs. The third parameter is a boolean indicating if the event should be fired during the capture phase or bubbling phase of the event flow. Typically a developer wants events to fire during the bubbling phase so that object eventing handles the event before bubbling the event up the DOM.
Because of this you almost always provide a false value as the last argument to the addEventListener. In modern browsers if the 3rd parameter is not specified it will default to false. The removeEventListener method can be used to remove events listeners, if the orginal listener was not added using an anonymous function.
In the code below I add two events listeners to the HTML document and attempt to remove both of them. However, only the listener that was attached using a function reference is removed.