SlideShare a Scribd company logo
1 of 79
Download to read offline
The DOM is a Mess
                  John Resig
http://ejohn.org/ - http://twitter.com/jeresig/
A Tour of the DOM
    A messy DOM
✦

    Writing Cross-Browser Code
✦

    Common Features
✦
    ✦ CSS Selector Engine
    ✦ DOM Modification
    ✦ Events
Messy
    Nearly every DOM method is broken in
✦
    some way, in some browser.
    Some old:
✦
    ✦ getElementById
    ✦ getElementsByTagName

    Some new:
✦
    ✦ getElementsByClassName
    ✦ querySelectorAll
getElementById
    Likely the most commonly used DOM
✦
    method
    A couple weird bits:
✦
    ✦ IE and older versions of Opera returning
      elements with a name == id
    ✦ Does not easily work in XML
      documents
getElementsByTagName
    Likely tied for most-commonly-used
✦
    DOM method
    Riddled with bugs in IE:
✦
    ✦ “*” returns no elements in IE 5.5
    ✦ “*” returns no elements on <object>
      elements in IE 7
    ✦ .length gets overwritten in IE if an
      element with an ID=”length” is found
getElementsByClassName
    Landed in Firefox 3, Safari 3, Opera 9.6
✦

    A few knotty issues:
✦
    ✦ HTMLElement.prototype
       .getElementsByClassName
      couldn’t be overwritten in Firefox
    ✦ Opera doesn’t match a second-specified
      class (e.g. class=”a b”, b isn’t found)
querySelectorAll
    Find DOM elements using CSS selectors
✦

    In Firefox 3.1, Safari 3.1, Opera 10, IE 8
✦

    Birthing pains:
✦
    ✦ Doesn’t exist in quirks mode, in IE 8
    ✦ Safari 3.1 had memory out of bounds
      problems
    ✦ Safari 3.2 can’t match uppercase
      characters in quirks mode
    ✦ #id doesn’t match in XML documents
Moral
    If there’s a DOM method, there’s probably
✦
    a problem with it somewhere, in some
    capacity.
Cross-Browser Code
Strategies
    Pick your browsers
✦

    Know your enemies
✦

    Write your code
✦
Cost / Benefit




  IE 7     IE 6          FF 3    Safari 3   Opera 9.5
                  Cost          Benefit


         Draw a line in the sand.
Graded Support




   Yahoo Browser Compatibility
Browser Support Grid
           IE      Firefox   Safari   Opera Chrome


Previous   6.0       2.0      3.0      9.5


Current    7.0       3.0      3.2      9.6   Current


 Next      8.0       3.1      4.0     10.0

                 jQuery Browser Support
Browser Support Grid
           IE        Firefox   Safari   Opera Chrome


Previous                        3.0      9.5
           6.0         2.0


Current    7.0         3.0      3.2      9.6   Current


 Next                  3.1      4.0
           8.0                          10.0

                 jQuery 1.3 Browser Support
Know Your Enemies
          Points of Concern for JavaScript Code



                     Browser Bugs
                                          Regressions

Missing Features     JavaScript Code

                                            Bug Fixes
                       External
                     Code, Markup
Know Your Enemies
          Points of Concern for JavaScript Code



                     Browser Bugs
                                          Regressions

Missing Features     JavaScript Code

                                            Bug Fixes
                       External
                     Code, Markup
Browser Bugs
    Generally your primary concern
✦

    Your defense is a good test suite
✦
    ✦ Prevent library regressions
    ✦ Analyze upcoming browser releases

    Your offense is feature simulation
✦

    What is a bug?
✦
    ✦ Is unspecified, undocumented, behavior
      capable of being buggy?
Test, Test, Test


1446 Tests, 9 browsers
Know Your Enemies
          Points of Concern for JavaScript Code



                     Browser Bugs
                                          Regressions

Missing Features     JavaScript Code

                                            Bug Fixes
                       External
                     Code, Markup
External Code
    Making your code resistant to any
✦
    environment
    ✦ Found through trial and error
    ✦ Integrate into your test suite
      ✦ Other libraries
      ✦ Strange code uses
Environment Testing
    100% Passing:
✦
    ✦ Standards Mode
    ✦ Quirks Mode
    ✦ Inline with Prototype + Scriptaculous
    ✦ Inline with MooTools

    Work in Progress:
✦
    ✦ XHTML w/ correct mimetype
    ✦ With Object.prototype
    ✦ In XUL (Firefox Extensions)
    ✦ In Rhino (with Env.js)
Object.prototype
 Object.prototype.otherKey = quot;otherValuequot;; 
  
 var obj = { key: quot;valuequot; }; 
 for ( var prop in object ) { 
   if ( object.hasOwnProperty( prop ) ) { 
     assert( prop, quot;keyquot;, 
      quot;There should only be one iterated property.quot; ); 
   } 
 } 
Greedy IDs
 <form id=quot;formquot;> 
   <input type=quot;textquot; id=quot;lengthquot;/> 
   <input type=quot;submitquot; id=quot;submitquot;/> 
 </form> 

document.getElementsByTagName(quot;inputquot;).length
Order of Stylesheets
    Putting stylesheets before code guarantees
✦
    that they’ll load before the code runs.
    Putting them after can create an
✦
    indeterminate situation.
Pollution
    Make sure your code doesn’t break
✦
    outside code
    ✦ Use strict code namespacing
    ✦ Don’t extend outside objects, elements

    Bad:
✦
    ✦ Introducing global variables
    ✦ Extending native objects (Array, Object)
    ✦ Extending DOM natives
Pollution




            http://mankz.com/code/
               GlobalCheck.htm
Know Your Enemies
          Points of Concern for JavaScript Code



                     Browser Bugs
                                          Regressions

Missing Features     JavaScript Code

                                            Bug Fixes
                       External
                     Code, Markup
Missing Features
    Typically older browsers missing specific
✦
    features
    Optimal solution is to gracefully
✦
    degrade
    ✦ Fall back to a simplified page

    Can’t make assumptions about
✦
    browsers that you can’t support
    ✦ If it’s impossible to test them, you must
      provide a graceful fallback
    Object detection works well here.
✦
Object Detection
    Check to see if an object or property
✦
    exists
    Useful for detecting an APIs existence
✦

    Doesn’t test the compatibility of an API
✦
    ✦ Bugs can still exist - need to test
      those separately with feature simulation
Event Binding
 function attachEvent( elem, type, handle ) { 
   // bind event using proper DOM means 
   if ( elem.addEventListener ) 
     elem.addEventListener(type, handle, false); 
      
   // use the Internet Explorer API 
   else if ( elem.attachEvent ) 
     elem.attachEvent(quot;onquot; + type, handle); 
 } 
Fallback Detection
 if ( typeof document !== quot;undefinedquot; &&  
      (document.addEventListener 
       || document.attachEvent) && 
      document.getElementsByTagName && 
      document.getElementById ) { 
   // We have enough of an API to 
   // work with to build our application 
 } else { 
   // Provide Fallback 
 }
Fallback
    Figure out a way to reduce the
✦
    experience
    Opt to not execute any JavaScript
✦
    ✦ Guarantee no partial API
      ✦ (e.g. DOM traversal, but no Events)

    Redirect to another page, or just work
✦
    unobtrusively
    Working on a ready() fallback for jQuery
✦
Know Your Enemies
          Points of Concern for JavaScript Code



                     Browser Bugs
                                          Regressions

Missing Features     JavaScript Code

                                            Bug Fixes
                       External
                     Code, Markup
Bug Fixes
    Don’t make assumptions about browser
✦
    bugs.
    ✦ Assuming that a browser will always
      have a bug is foolhardy
    ✦ You will become susceptible to fixes
    ✦ Browsers will become less inclined to fix
      bugs
    Look to standards to make decisions about
✦
    what are bugs
Failed Bug Fix in FF 3
 // Shouldn't work 
 var node = documentA.createElement(quot;divquot;); 
 documentB.documentElement.appendChild( node ); 
  
 // Proper way 
 var node = documentA.createElement(quot;divquot;); 
 documentB.adoptNode( node ); 
 documentB.documentElement.appendChild( node ); 
Feature Simulation
    More advanced than object detection
✦

    Make sure an API works as advertised
✦

    Able to capture bug fixes gracefully
✦
Verify API
 // Run once, at the beginning of the program 
 var ELEMENTS_ONLY = (function(){ 
   var div = document.createElement(quot;divquot;); 
   div.appendChild( document.createComment(quot;testquot; ) ); 
   return div.getElementsByTagName(quot;*quot;).length === 0; 
 })(); 
  
 // Later on: 
 var all = document.getElementsByTagName(quot;*quot;); 
  
 if ( ELEMENTS_ONLY ) { 
   for ( var i = 0; i < all.length; i++ ) { 
     action( all[i] ); 
   } 
 } else { 
   for ( var i = 0; i < all.length; i++ ) { 
     if ( all[i].nodeType === 1 ) { 
       action( all[i] ); 
     } 
   } 
 } 
Figure Out Naming
 <div id=quot;testquot; style=quot;color:red;quot;></div> 
 <div id=quot;test2quot;></div> 
 <script> 
 // Perform the initial attribute check 
 var STYLE_NAME = (function(){ 
   var div = document.createElement(quot;divquot;); 
   div.style.color = quot;redquot;; 
    
   if ( div.getAttribute(quot;stylequot;) ) 
     return quot;stylequot;; 
    
   if ( div.getAttribute(quot;cssTextquot;) ) 
     return quot;cssTextquot;; 
 })(); 
  
 // Later on: 
 window.onload = function(){ 
   document.getElementsById(quot;test2quot;).setAttribute( STYLE_NAME, 
       document.getElementById(quot;testquot;).getAttribute( STYLE_NAME ) ); 
 }; 
 </script> 
Know Your Enemies
          Points of Concern for JavaScript Code



                     Browser Bugs
                                          Regressions

Missing Features     JavaScript Code

                                            Bug Fixes
                       External
                     Code, Markup
Regressions
    Removing or changing unspecified APIs
✦

    Object detection helps here
✦

    Monitor upcoming browser releases
✦
    ✦ All vendors provide access to beta
      releases
    ✦ Diligence!

    Example: IE 7 introduced
✦
    XMLHttpRequest with file:// bug
    Test Suite Integration
✦
Object Failover
 function attachEvent( elem, type, handle ) { 
   // bind event using proper DOM means 
   if ( elem.addEventListener ) 
     elem.addEventListener(type, handle, false); 
      
   // use the Internet Explorer API 
   else if ( elem.attachEvent ) 
     elem.attachEvent(quot;onquot; + type, handle); 
 } 
Safe Cross-Browser Fixes
    The easiest form of fix
✦

    Unifies an API across browsers
✦

    Implementation is painless
✦
Unify Dimensions
 // ignore negative width and height values 
 if ( (key == 'width' || key == 'height') && 
      parseFloat(value) < 0 ) 
   value = undefined; 
Prevent Breakage
 if ( name == quot;typequot; && elem.nodeName.toLowerCase() 
       == quot;inputquot; && elem.parentNode ) 
   throw quot;type attribute can't be changedquot;; 
Untestable Problems
    Has an event handler been bound?
✦

    Will an event fire?
✦

    Do CSS properties like color or opacity
✦
    actually affect the display?
    Problems that cause a browser crash.
✦

    Problems that cause an incongruous API.
✦
Impractical to Test
    Performance-related issues
✦

    Determining if Ajax requests will work
✦
Battle of Assumptions
    Cross-browser development is all about
✦
    reducing the number of assumptions
    No assumptions indicates perfect code
✦
    ✦ Unfortunately that’s an unobtainable
      goal
    ✦ Prohibitively expensive to write

    Have to draw a line at some point
✦
DOM Traversal
    Many methods of DOM traversal
✦

    One unanimous solution:
✦
    ✦ CSS Selector Engine
Traditional DOM
    getElementsByTagName
✦

    getElementById
✦

    getElementsByClassName
✦
    ✦ in FF3, Safari 3, Opera 9.6

    .children
✦
    ✦ only returns elements (in all, and FF 3.1)

    getElementsByName
✦

    .all[id]
✦
    ✦ Match multiple elements by ID
Top-Down CSS Selector
    Traditional style of traversal
✦
    ✦ Used by all major libraries

    Work from left-to-right
✦

    “div p”
✦
    ✦ Find all divs, find paragraphs inside

    Requires a lot of result merging
✦

    And removal of duplicates
✦
   function find(selector, root){ 
     root = root || document; 
                                     
     var parts = selector.split(quot; quot;), 
       query = parts[0], 
       rest = parts.slice(1).join(quot; quot;), 
       elems = root.getElementsByTagName( query ), 
       results = []; 
                                     
     for ( var i = 0; i < elems.length; i++ ) { 
       if ( rest ) { 
         results = results.concat( find(rest, elems[i]) ); 
       } else { 
         results.push( elems[i] ); 
       } 
     } 
                                     
     return results; 
   } 
 (function(){ 
   var run = 0; 
                                     
   this.unique = function( array ) { 
     var ret = []; 
                                       
     run++; 
                                   
     for ( var i = 0, length = array.length; i < length; i++ ) { 
       var elem = array[ i ]; 
                                   
       if ( elem.uniqueID !== run ) { 
         elem.uniqueID = run; 
         ret.push( array[ i ] ); 
       } 
     } 
                                   
     return ret; 
   }; 
 })(); 
Bottom-Up
    Work from right-to-left
✦
    ✦ (How CSS Engines work in browsers.)

    “div p”
✦
    ✦ Find all paragraphs, see if they have a div
      ancestor, etc.
    Fast for specific queries
✦
    ✦ “div #foo”

    Deep queries get slow (in comparison)
✦
    ✦ “#foo p”
Bottom-Up
    Some nice features:
✦
    ✦ Only one DOM query
    ✦ No merge/unique required (except for
      “div, span”)
    ✦ Everything is a process of filtering
   function find(selector, root){ 
     root = root || document; 
                                            
     var parts = selector.split(quot; quot;), 
       query = parts[parts.length - 1], 
       rest = parts.slice(0,-1).join(quot;quot;).toUpperCase(), 
       elems = root.getElementsByTagName( query ), 
       results = []; 
                                             
     for ( var i = 0; i < elems.length; i++ ) { 
       if ( rest ) { 
         var parent = elems[i].parentNode; 
         while ( parent && parent.nodeName != rest ) { 
           parent = parent.parentNode; 
         } 
                                                 
         if ( parent ) { 
           results.push( elems[i] ); 
         } 
       } else { 
         results.push( elems[i] ); 
       } 
     } 
                                             
     return results; 
   } 
CSS to XPath
    Browsers provide XPath functionality
✦

    Collect elements from a document
✦

    Works in all browsers
✦
    ✦ In IE it only works on HTML
      documents
    Fast for a number of selectors (.class, “div
✦
    div div”)
    ✦ Slow for some others: #id

    Currently used by Dojo and Prototype
✦
 if ( typeof document.evaluate === quot;functionquot; ) { 
   function getElementsByXPath(expression, parentElement) { 
     var results = []; 
     var query = document.evaluate(expression, parentElement || document, 
       null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 
     for (var i = 0, length = query.snapshotLength; i < length; i++) 
       results.push(query.snapshotItem(i)); 
     return results; 
   } 
 } 
Goal                        CSS 3                 XPath

All Elements                 *                   //*

All P Elements               p                   //p

All Child Elements           p>*                 //p/*

Element By ID                #foo                //*[@id='foo']

                                                 //*[contains(concat(quot; quot;,
Element By Class             .foo
                                                 @class, quot; quot;),quot; foo quot;)]

Element With Attribute       *[title]            //*[@title]

First Child of All P         p > *:first-child    //p/*[0]

All P with an A descendant                       //p[a]
                             Not possible

Next Element                 p+*                 //p/following-sibling::*[0]
querySelectorAll
    The Selectors API spec from the W3C
✦

    Two methods:
✦
    ✦ querySelector (first element)
    ✦ querySelectorAll (all elements)

    Works on:
✦
    ✦ document
    ✦ elements
    ✦ DocumentFragments

    Implemented in:
✦
    ✦ Firefox 3.1, Safari 3, Opera 10, IE 8
 <div id=quot;testquot;> 
   <b>Hello</b>, I'm a ninja! 
 </div> 
 <div id=quot;test2quot;></div> 
 <script> 
 window.onload = function(){ 
   var divs = document.querySelectorAll(quot;body > divquot;); 
   assert( divs.length === 2, quot;Two divs found using a CSS selector.quot; ); 
                                         
   var b = document.getElementById(quot;testquot;).querySelector(quot;b:only-childquot;); 
   assert( b, quot;The bold element was found relative to another element.quot; );
 }; 
 </script> 
 <div id=quot;testquot;> 
   <b>Hello</b>, I'm a ninja! 
 </div> 
 <script> 
 window.onload = function(){ 
   var b = document.getElementById(quot;testquot;).querySelector(quot;div bquot;); 
   assert( b, quot;Only the last part of the selector matters.quot; );
 }; 
 </script> 
DOM Modification
    Injecting HTML
✦

    Removing Elements
✦
Injecting HTML
    HTML 5:
✦
    insertAdjacentHTML
    Already in IE, dicey support, at best
✦

    What can we use instead?
✦
    ✦ We must generate our own HTML
      injection
    ✦ Use innerHTML to generate a DOM
 function getNodes(htmlString){ 
   var map = { 
     quot;<tdquot;: [3, quot;<table><tbody><tr>quot;, quot;</tr></tbody></table>quot;], 
     quot;<optionquot;: [1, quot;<select multiple='multiple'>quot;, quot;</select>quot;] 
     // a full list of all element fixes 
   }; 
                                         
   var name = htmlString.match(/<w+/), 
     node = name ? map[ name[0] ] || [0, quot;quot;, quot;quot;]; 
                                         
   var div = document.createElement(quot;divquot;); 
   div.innerHTML = node[1] + htmlString + node[2]; 
                                         
   while ( node[0]-- ) 
     div = div.lastChild; 
                                         
   return div.childNodes; 
 } 
                                       
 assert( getNodes(quot;<td>test</td><td>test2</td>quot;).length === 2, 
   quot;Get two nodes back from the method.quot; ); 
 assert( getNodes(quot;<td>test</td>quot;).nodeName === quot;TDquot;, 
   quot;Verify that we're getting the right node.quot; ); 
Element Mappings
    option and optgroup need to be contained in a
✦
       <select multiple=quot;multiplequot;>...</select>
    legend need to be contained in a
✦
       <fieldset>...</fieldset>
    thead, tbody, tfoot, colgroup, and caption need to be
✦
        contained in a <table>...</table>
    tr need to be in a
✦
       <table><thead>...</thead></table>,
       <table><tbody>...</tbody></table>, or a
       <table><tfoot>...</tfoot></table>
    td and th need to be in a
✦
       <table><tbody><tr>...</tr></tbody></table>
    col in a
✦
       <table><tbody></tbody><colgroup>...</
       colgroup></table>
    link and script need to be in a
✦
       div<div>...</div>
DocumentFragment
    Fragments can collect nodes
✦

    Can be appended or cloned in bulk
✦

    Super-fast (2-3x faster than normal)
✦
   function insert(elems, args, callback){ 
     if ( elems.length ) { 
       var doc = elems[0].ownerDocument || elems[0], 
         fragment = doc.createDocumentFragment(), 
         scripts = getNodes( args, doc, fragment ), 
         first = fragment.firstChild; 
                                             
       if ( first ) { 
         for ( var i = 0; elems[i]; i++ ) { 
           callback.call( root(elems[i], first),  
             i > 0 ? fragment.cloneNode(true) : fragment ); 
         } 
       } 
     } 
   } 
                                           
   var divs = document.getElementsByTagName(quot;divquot;); 
                                           
   insert(divs, [quot;Name:quot;], function(fragment){ 
     this.appendChild( fragment ); 
   }); 
                                           
   insert(divs, [quot;First Lastquot;], function(fragment){ 
     this.parentNode.insertBefore( fragment, this ); 
   }); 
Inline Script Execution
    .append(“<script>var foo = 5;</script>”);
✦

    Must execute scripts globally
✦

    window.execScript() (for IE)
✦

    eval.call( window, “var foo = 5;” );
✦

    Cross-browser way is to build a script
✦
    element then inject it
    ✦ Executes globally
 function globalEval( data ) { 
   data = data.replace(/^s+|s+$/g, quot;quot;); 
                                                 
   if ( data ) { 
     var head = document.getElementsByTagName(quot;headquot;)[0] || document.documentElement, 
       script = document.createElement(quot;scriptquot;); 
                                                  
     script.type = quot;text/javascriptquot;; 
     script.text = data; 
                                                  
     head.insertBefore( script, head.firstChild ); 
     head.removeChild( script ); 
   } 
 } 
Removing Elements
    Have to clean up bound events
✦
    ✦ IE memory leaks

    Easy to do if it’s managed.
✦
Events
    Three big problems with Events:
✦
    ✦ Memory Leaks (in IE)
    ✦ Maintaining ‘this’ (in IE)
    ✦ Fixing event object inconsistencies
Leaks
    Internet Explorer 6 leaks horribly
✦
    ✦ Other IEs still leak, not so badly

    Attaching functions (that have a closure to
✦
    another node) as properties
    Makes a leak:
✦
    elem.test = function(){
      anotherElem.className = “foo”;
    };
‘this’
    Users like having their ‘this’ refer to the
✦
    target element
    Not the case in IE
✦

    What’s the solution?
✦
Single Handler
    Bind a single handler to an event
✦

    Call each bound function individually
✦

    Can fix ‘this’ and event object
✦

    How do we store the bound functions in a
✦
    way that won’t leak?
Central Data Store
    Store all bound event handlers in a central
✦
    object
    Link elements to handlers
✦

    Keep good separation
✦

    One data store per library instance
✦

    Easy to manipulate later
✦
    ✦ Trigger individual handlers
    ✦ Easy to remove again, later
Central Data Store
                   Events                Data
Element            function click(){}

          #43
                function mouseover(){}


Element
                                         Data
Element
          #67
Element
                   Events
Element            function click(){}

          #22
                   function click(){}




                            Data Store
Multiple Stores
Element
           #43
                  Library A
Element
            #67
Element

Element
          #37
Element
           #22    Library B
Unique Element ID
    The structure must hook to an element
✦

    Elements don’t have unique IDs
✦

    Must generate them and manage them
✦

    jQuery.data( elem, “events” );
✦

    Unique attribute name:
✦
    ✦ elem.jQuery123456789 = 45;
    ✦ Prevents collisions with other libraries

    We can store all sorts of data in here
✦
Questions?
    http://ejohn.org/
✦

    http://twitter.com/jeresig/
✦

More Related Content

What's hot

Amazon EKS上の開発体験を最大化するプレビュー環境の作り方
Amazon EKS上の開発体験を最大化するプレビュー環境の作り方Amazon EKS上の開発体験を最大化するプレビュー環境の作り方
Amazon EKS上の開発体験を最大化するプレビュー環境の作り方
理弘 山崎
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
智啓 出川
 

What's hot (20)

Amazon EKS上の開発体験を最大化するプレビュー環境の作り方
Amazon EKS上の開発体験を最大化するプレビュー環境の作り方Amazon EKS上の開発体験を最大化するプレビュー環境の作り方
Amazon EKS上の開発体験を最大化するプレビュー環境の作り方
 
MySQLとPostgreSQLの基本的な実行プラン比較
MySQLとPostgreSQLの基本的な実行プラン比較MySQLとPostgreSQLの基本的な実行プラン比較
MySQLとPostgreSQLの基本的な実行プラン比較
 
"Шістдесятництво" як явище української культури
"Шістдесятництво" як явище української культури"Шістдесятництво" як явище української культури
"Шістдесятництво" як явище української культури
 
Basic of virtual memory of Linux
Basic of virtual memory of LinuxBasic of virtual memory of Linux
Basic of virtual memory of Linux
 
「とても小さいVim」vim tiny
「とても小さいVim」vim tiny「とても小さいVim」vim tiny
「とても小さいVim」vim tiny
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
 
Smart SE: コロナ時代のAI・IoTの社会人オン・オフライン教育
Smart SE: コロナ時代のAI・IoTの社会人オン・オフライン教育Smart SE: コロナ時代のAI・IoTの社会人オン・オフライン教育
Smart SE: コロナ時代のAI・IoTの社会人オン・オフライン教育
 
공간정보거점대학 PostGIS 고급과정
공간정보거점대학 PostGIS 고급과정공간정보거점대학 PostGIS 고급과정
공간정보거점대학 PostGIS 고급과정
 
Java Memory Analysis: Problems and Solutions
Java Memory Analysis: Problems and SolutionsJava Memory Analysis: Problems and Solutions
Java Memory Analysis: Problems and Solutions
 
QGISセミナー初級・実践編(V2.4)
QGISセミナー初級・実践編(V2.4)QGISセミナー初級・実践編(V2.4)
QGISセミナー初級・実践編(V2.4)
 
はじめての Go 言語のプロジェクトを AWS Lambda + API Gateway でやったのでパッケージ構成を晒すよ
はじめての Go 言語のプロジェクトを AWS Lambda + API Gateway でやったのでパッケージ構成を晒すよはじめての Go 言語のプロジェクトを AWS Lambda + API Gateway でやったのでパッケージ構成を晒すよ
はじめての Go 言語のプロジェクトを AWS Lambda + API Gateway でやったのでパッケージ構成を晒すよ
 
量子コンピューター向け冷凍機について
量子コンピューター向け冷凍機について量子コンピューター向け冷凍機について
量子コンピューター向け冷凍機について
 
【初心者向け】API を使ってクラウドの管理を自動化しよう
【初心者向け】API を使ってクラウドの管理を自動化しよう【初心者向け】API を使ってクラウドの管理を自動化しよう
【初心者向け】API を使ってクラウドの管理を自動化しよう
 
LR parsing
LR parsingLR parsing
LR parsing
 
チームメイトのためにdocstringを書こう! pyconjp2019
チームメイトのためにdocstringを書こう! pyconjp2019チームメイトのためにdocstringを書こう! pyconjp2019
チームメイトのためにdocstringを書こう! pyconjp2019
 
QtとC++でGUIプログラミング
QtとC++でGUIプログラミングQtとC++でGUIプログラミング
QtとC++でGUIプログラミング
 
Mk data intensive-onic2021
Mk data intensive-onic2021Mk data intensive-onic2021
Mk data intensive-onic2021
 
Kubernetes on Azure ~Azureで便利にKubernetesを利用する~
Kubernetes on Azure ~Azureで便利にKubernetesを利用する~Kubernetes on Azure ~Azureで便利にKubernetesを利用する~
Kubernetes on Azure ~Azureで便利にKubernetesを利用する~
 
グラフデータベース:Neo4j、そしてRDBからの移行手順の紹介
グラフデータベース:Neo4j、そしてRDBからの移行手順の紹介グラフデータベース:Neo4j、そしてRDBからの移行手順の紹介
グラフデータベース:Neo4j、そしてRDBからの移行手順の紹介
 
About GStreamer 1.0 application development for beginners
About GStreamer 1.0 application development for beginnersAbout GStreamer 1.0 application development for beginners
About GStreamer 1.0 application development for beginners
 

Viewers also liked

Size exclusion chromatography
Size exclusion chromatographySize exclusion chromatography
Size exclusion chromatography
Mandvi Shandilya
 
61 Beautiful & Inspirational Timeline Cover on Facebook
61 Beautiful & Inspirational Timeline Cover on Facebook61 Beautiful & Inspirational Timeline Cover on Facebook
61 Beautiful & Inspirational Timeline Cover on Facebook
Consonaute
 

Viewers also liked (20)

Thai tech startup ecosystem report 2017
Thai tech startup ecosystem report 2017Thai tech startup ecosystem report 2017
Thai tech startup ecosystem report 2017
 
Mri brain anatomy Dr Muhammad Bin Zulfiqar
Mri brain anatomy Dr Muhammad Bin ZulfiqarMri brain anatomy Dr Muhammad Bin Zulfiqar
Mri brain anatomy Dr Muhammad Bin Zulfiqar
 
Mineral & energy resources
Mineral & energy resourcesMineral & energy resources
Mineral & energy resources
 
Size exclusion chromatography
Size exclusion chromatographySize exclusion chromatography
Size exclusion chromatography
 
Digital Brief 003 - Market Report Q2 2015
Digital Brief 003 - Market Report Q2 2015Digital Brief 003 - Market Report Q2 2015
Digital Brief 003 - Market Report Q2 2015
 
The Ultimate Guide to Creating Visually Appealing Content
The Ultimate Guide to Creating Visually Appealing ContentThe Ultimate Guide to Creating Visually Appealing Content
The Ultimate Guide to Creating Visually Appealing Content
 
5000 Sat Words With Definitions
5000 Sat Words With Definitions5000 Sat Words With Definitions
5000 Sat Words With Definitions
 
61 Beautiful & Inspirational Timeline Cover on Facebook
61 Beautiful & Inspirational Timeline Cover on Facebook61 Beautiful & Inspirational Timeline Cover on Facebook
61 Beautiful & Inspirational Timeline Cover on Facebook
 
Starting small, thinking big
Starting small, thinking bigStarting small, thinking big
Starting small, thinking big
 
Entrepreneurship, introduction to entrepreneurship, definition of entrepreneu...
Entrepreneurship, introduction to entrepreneurship, definition of entrepreneu...Entrepreneurship, introduction to entrepreneurship, definition of entrepreneu...
Entrepreneurship, introduction to entrepreneurship, definition of entrepreneu...
 
4. heredity and evolution
4. heredity and evolution4. heredity and evolution
4. heredity and evolution
 
Operating Systems - File Management
Operating Systems -  File ManagementOperating Systems -  File Management
Operating Systems - File Management
 
What Makes Great Infographics
What Makes Great InfographicsWhat Makes Great Infographics
What Makes Great Infographics
 
Loans and advances
Loans and advancesLoans and advances
Loans and advances
 
Masters of SlideShare
Masters of SlideShareMasters of SlideShare
Masters of SlideShare
 
STOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
STOP! VIEW THIS! 10-Step Checklist When Uploading to SlideshareSTOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
STOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
 
You Suck At PowerPoint!
You Suck At PowerPoint!You Suck At PowerPoint!
You Suck At PowerPoint!
 
Introduction to Excel - Excel 2013 Tutorial
Introduction to Excel - Excel 2013 TutorialIntroduction to Excel - Excel 2013 Tutorial
Introduction to Excel - Excel 2013 Tutorial
 
10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization
 
How To Get More From SlideShare - Super-Simple Tips For Content Marketing
How To Get More From SlideShare - Super-Simple Tips For Content MarketingHow To Get More From SlideShare - Super-Simple Tips For Content Marketing
How To Get More From SlideShare - Super-Simple Tips For Content Marketing
 

Similar to The DOM is a Mess @ Yahoo

Ajax Tutorial
Ajax TutorialAjax Tutorial
Ajax Tutorial
oscon2007
 

Similar to The DOM is a Mess @ Yahoo (20)

Building a JavaScript Library
Building a JavaScript LibraryBuilding a JavaScript Library
Building a JavaScript Library
 
Jazz up your JavaScript: Unobtrusive scripting with JavaScript libraries
Jazz up your JavaScript: Unobtrusive scripting with JavaScript librariesJazz up your JavaScript: Unobtrusive scripting with JavaScript libraries
Jazz up your JavaScript: Unobtrusive scripting with JavaScript libraries
 
Ajax Tutorial
Ajax TutorialAjax Tutorial
Ajax Tutorial
 
Performance, Games, and Distributed Testing in JavaScript
Performance, Games, and Distributed Testing in JavaScriptPerformance, Games, and Distributed Testing in JavaScript
Performance, Games, and Distributed Testing in JavaScript
 
Efficient JavaScript Development
Efficient JavaScript DevelopmentEfficient JavaScript Development
Efficient JavaScript Development
 
How to make Ajax Libraries work for you
How to make Ajax Libraries work for youHow to make Ajax Libraries work for you
How to make Ajax Libraries work for you
 
Here Be Dragons – Advanced JavaScript Debugging
Here Be Dragons – Advanced JavaScript DebuggingHere Be Dragons – Advanced JavaScript Debugging
Here Be Dragons – Advanced JavaScript Debugging
 
FITC - Here Be Dragons: Advanced JavaScript Debugging
FITC - Here Be Dragons: Advanced JavaScript DebuggingFITC - Here Be Dragons: Advanced JavaScript Debugging
FITC - Here Be Dragons: Advanced JavaScript Debugging
 
Efficient JavaScript Development
Efficient JavaScript DevelopmentEfficient JavaScript Development
Efficient JavaScript Development
 
JavaScript 2.0 in Dreamweaver CS4
JavaScript 2.0 in Dreamweaver CS4JavaScript 2.0 in Dreamweaver CS4
JavaScript 2.0 in Dreamweaver CS4
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
 
Browsers
BrowsersBrowsers
Browsers
 
Web a Quebec - JS Debugging
Web a Quebec - JS DebuggingWeb a Quebec - JS Debugging
Web a Quebec - JS Debugging
 
Os Alrubaie
Os AlrubaieOs Alrubaie
Os Alrubaie
 
Os Alrubaie
Os AlrubaieOs Alrubaie
Os Alrubaie
 
Reverse Engineering Malicious Javascript
Reverse Engineering Malicious JavascriptReverse Engineering Malicious Javascript
Reverse Engineering Malicious Javascript
 
Dconrails Gecco Presentation
Dconrails Gecco PresentationDconrails Gecco Presentation
Dconrails Gecco Presentation
 
Front end performance tip
Front end performance tipFront end performance tip
Front end performance tip
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manor
 
Lightning Talk: JavaScript Error Handling
Lightning Talk: JavaScript Error HandlingLightning Talk: JavaScript Error Handling
Lightning Talk: JavaScript Error Handling
 

More from jeresig

JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)
jeresig
 
Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)
jeresig
 
jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)
jeresig
 
jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)
jeresig
 
jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)
jeresig
 

More from jeresig (20)

Does Coding Every Day Matter?
Does Coding Every Day Matter?Does Coding Every Day Matter?
Does Coding Every Day Matter?
 
Accidentally Becoming a Digital Librarian
Accidentally Becoming a Digital LibrarianAccidentally Becoming a Digital Librarian
Accidentally Becoming a Digital Librarian
 
2014: John's Favorite Thing (Neo4j)
2014: John's Favorite Thing (Neo4j)2014: John's Favorite Thing (Neo4j)
2014: John's Favorite Thing (Neo4j)
 
Computer Vision as Art Historical Investigation
Computer Vision as Art Historical InvestigationComputer Vision as Art Historical Investigation
Computer Vision as Art Historical Investigation
 
Hacking Art History
Hacking Art HistoryHacking Art History
Hacking Art History
 
Using JS to teach JS at Khan Academy
Using JS to teach JS at Khan AcademyUsing JS to teach JS at Khan Academy
Using JS to teach JS at Khan Academy
 
Applying Computer Vision to Art History
Applying Computer Vision to Art HistoryApplying Computer Vision to Art History
Applying Computer Vision to Art History
 
NYARC 2014: Frick/Zeri Results
NYARC 2014: Frick/Zeri ResultsNYARC 2014: Frick/Zeri Results
NYARC 2014: Frick/Zeri Results
 
EmpireJS: Hacking Art with Node js and Image Analysis
EmpireJS: Hacking Art with Node js and Image AnalysisEmpireJS: Hacking Art with Node js and Image Analysis
EmpireJS: Hacking Art with Node js and Image Analysis
 
Applying Computer Vision to Art History
Applying Computer Vision to Art HistoryApplying Computer Vision to Art History
Applying Computer Vision to Art History
 
JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)
 
Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)
 
jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)
 
jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)
 
jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)
 
jQuery Mobile
jQuery MobilejQuery Mobile
jQuery Mobile
 
jQuery Open Source (Fronteer 2011)
jQuery Open Source (Fronteer 2011)jQuery Open Source (Fronteer 2011)
jQuery Open Source (Fronteer 2011)
 
Holistic JavaScript Performance
Holistic JavaScript PerformanceHolistic JavaScript Performance
Holistic JavaScript Performance
 
New Features Coming in Browsers (RIT '09)
New Features Coming in Browsers (RIT '09)New Features Coming in Browsers (RIT '09)
New Features Coming in Browsers (RIT '09)
 
Introduction to jQuery (Ajax Exp 2007)
Introduction to jQuery (Ajax Exp 2007)Introduction to jQuery (Ajax Exp 2007)
Introduction to jQuery (Ajax Exp 2007)
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 

The DOM is a Mess @ Yahoo