The Theory of The DOM with Doug Crockford

Lecture from http://video.yahoo.com/video/play?vid=111582
http://yuiblog.com/assets/crockford/theory.zip

Browser is source of pain and misery. Can't talk about all the quirks. Talk about the theory of the DOM.
  • Rule breaking
  • Corporate warfare
  • Extreme Time pressure
Started in 1995. Frontline of browser war. MS and NS attacked each other through API incompatibility. Server traps evaded, browser traps remained.

Jesse James Garrett named DHTML AJAX during Pax Microsoft. The browser became stable enough to think of it as a application platform.

URL Flow Paint. FF 1.5 2.0, safari 2.0, IE 5.5, 6, 7, NS 8, Opera 9 "The A List" browsers.

hack for mosaic and navigator 1.0, so it's not needed anymore. Not necessary for 10 years. language=javascript is deprecated. type=text/javascript ignored (problem: MIME type wasn't issued till this year, ignored when loading from source URL). src=URL is very good, added in Navigator 3.

Put script src tags as low in the body of the page as possible. Put CSS as high in head as possible.

Gzip javascript. take advantage of cache headers. For a while, put javascript in one file until widely deployed.

Document.write not recommended. Better alternatives. Sensitive to when you call it. If you call before onload, it's fine, calling after it destroys document.

Lots of collections defined; don't use them either. document.anchors, .applets, .embeds, .forms, .frames, .images, .plugins, .scripts, .stylesheets.

name vs id: used be interchangable, but now use name for form data. used to correlate radio buttons, name window or frame. id uniquely identifies elements to get access.

avoid document.all. Introduced by Microsoft; rejected by W3C.

use document.getElementById(id), .getElementsByName(name), .getElementsByTagName(tag) [can call on any node]

Node or tag names retrieved may be in upper case. Browser will add document and head nodes even if not present. IE and Firefox create a different tree because W3C requires whitespace to be captured. (Which sucks but it's a standard, except for IE).

You have complex pointers, but you only need a subset. You can get by with firstChild, nextSibling:

function walkTheDOM(node, func){
func(node);
while(node){
walkTheDOM(node, func);
node = node.nextSibling
}
}

w3c forgot getElementsByClassName - you can use the above for that. To access class attribute, use .className because class is a reserved word.


Part 2

manipulating elements
  1. old school: img.src = 'someurl'; - smaller and faster, probably preferred.
  2. new school img.setAttribute('src', 'someurl'); - recommended by w3c; set has side effect, so that's nice.
Changing style
  1. node.className = 'myClass'; //note can have multiple classes with space between.
  2. node.style.mystyle
  3. to get css style: IE only: node.currentStyle. w3c: document.defaultView().getComputedStyle(mynode, "").getPropertyValue('mystyle');
  4. to read style info you have to do it both ways. Ugh.
  5. unfortunate naming conventions: css properties are camel case. "should have been designed better."
Making elements (2 6:15)
  1. document.createElement(tagName)
  2. document.createTextNode(text)
  3. node.cloneNode()
  4. node.cloneNode(true) - include all descendants (Q: is there ever a time that you can't do this?)
  5. new nodes aren't connected to the document yet.
Linking Elements
  1. node.appendChild(newNode)
  2. node.insertBefore(newNode, sibling)
  3. node.replaceChild(newNode, oldNode)
  4. old.parentNode.replaceChild(new, old) - weird that you have to specify old twice! w3c screwup - or at least doug doesn't agree with it. :)
removing elements
  1. old.parentnode.removeChild(old) - returns the old node
  2. make sure you remove all event handlers from the oldfirst.
HTML parsing
  1. w3c doesn't provide access to html parser [q: what does this mean? they wanted you to write an html parser and manipulate the dom directly]
  2. Microsoft defined the de facto standard, innerHTML property that all browsers support. Set html here and the parser will insert it into the tree.
Which way is better? Create nodes or pass HTML? A: do what makes your code cleaner and easier to maintain.

Event Model

events single threaded async
always targeted to a node (the top most node containing the cursor)
  1. click
  2. dblclick
  3. mousedown
  4. mousemove
  5. mouseout
  6. mouseover
  7. mouseup
Input events
  1. blur
  2. change
  3. focus
  4. keydown
  5. keypress
  6. keyup
  7. reset
  8. submit
Three ways to attach handlers
  1. node.["on" + type] = f; works on all browsers
  2. node.attachEvent("on" + type, f); MS only
  3. node.addEventListener(type, f, false); w3c - note that type doesn't have "on" in front. last parm is always false
Handlers
take an optional event object. MS puts the event in the global namespace. Use this boilerplate to deal with it:
handler(e){
e= e || event; //if e is falsy, get it from global namespace
var target = e.target || e.srcElement;
}

Trickling and Bubbling - how events propogate
  • trickle: events go from the top node and go down, letting nodes respond
  • bubble: events go from bottom and up to the top.
  • w3c does both - first trickle down, then bubble up. that's what the 3rd parm defines.
  • why bubble? you can attach event listener to parent!!! vs attaching to a bunch of elts.
  • it doesn't stop bubbling - the handler has to be explicit
    • e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation();
    • or use a platform library
  • after the handler finishes the browser takes default action unless you tell it otherwise
    • e.returnValue = false; if (e.preventDefault) e.preventDefault();
    • or use a platform library
Video 3

memory management
  • auto garbage collected
  • possible to hold onto too much state - programmatic error. set to null to let it release.
  • biggest leak in IE6: explicitly remove event handlers before remove them from the DOM. IE6 uses reference counting GC. (that doesn't work with cycles). Didn't show up for a long time because not much script was running and long running pages on the screen. Fixed in IE7. do before removeChild or removeChildren and innerHTML
function purgeEventHandlers(node){
walkTheDOM(node, function(e) {
for (var n in e) {
if (typeof e[n] === 'function') {
e[n] = null;
}
}
)};
}(walk the dom defined elsewhere)

JavaScript features
  1. alert - don't use in ajax - it blocks the browser thread. use platform library instead
  2. confirm -
  3. prompt
  4. setTimeout, set interval
Window
  1. window object is the JavaScript global object
  2. every window, frame, iframe has unique window object.
  3. aka self, parent, top.
Inter-window communication
  1. frames[] - child frames and iframes
  2. name - text name of a window
  3. opener - reference to open
  4. parent
  5. self - reference to this window [what does that mean? from the perspective of the script?]
  6. top - reference to outermost window
  7. window - reference to this window
  8. open() - open a new window - sometimes work but sometimes doesn't. this is what popup blockers block
Interwindow security - 2 rules
  1. can access another window if it can get a reference to it e.g. document.domain === otherwindow.document.domain (won't work with subdomains, unless both scripts shorten their domain to the TLD only)
  2. same origin policy
Cross Browser - shouldn't be an issue, but is. (is that naive?)
  1. Browser detection - not recommended because browsers lie; brittle. (see PPK)
  2. Feature detection - use reflection capabilities
  3. Platform libraries - YAHOO.util.Event developer.yahoo.com/yui
    1. 200 ajax libraries or so, comprehensive minimal, small large team
    2. Doug guesses there will be two winners: MS Atlas (strongest toolset, documentation, support), YUI could be the other winner (minimal, but extensible, best documented, free).
    3. why? real need for api for applications, fun to make
The Cracks of DOM
  • Writing to multiple buglists
  • DOM isn't described fully anywhere - w3c specs aren't complete
  • "skating across 5 layers of cracked ice"
Do what works.
Do what is common.
Do what is standard.

The wall
  1. browsers getting pushed ot limit: memory, balance of client and server. Photo3d hit the wall.
The hole
  1. not designed to be app platform:
  2. lacks compositing model;
  3. accessibility suffers;
  4. lacks support for cooperation under mutual suspicion. Cannot protect mashup components from each other. Be careful about mixing private data.
The peace is ending. MS disbanded the IE team after winning. Firefox made the IE team get back together. 4 major browser makers.

No comments: