DOM
DOM =
window.document
BOM =
window.document, window.navigator, window.location, window.history, window.screen, etc
in DevTool,
$0
returns the selected Element, so you can use normal DOM APIs to access: ex,$0.classList
DOM Ready
event
DOMContentLoaded
: the browser fully loaded HTML, and the DOM tree is built, but external resources like pictures<img>
and stylesheets may be not yet loaded.document.addEventListener("DOMContentLoaded", ready);
the
defer
scripts already loadedthe
async
scripts might NOT be loaded
function
load
: the browser loaded all resources (images, styles etc)window.onload = function() {}
function
beforeunload/unload
: when the user is leaving the pagewindow.unload = function() {}
Reference: https://javascript.info/onload-ondomcontentloaded
Script: async vs defer
Normally, if browser see
<script>
in<head>
, it will stop parsing until downloadedscript in bottom of the body will not block. But its own problem is, the script won't be downloaded until the full page is parsed.
defer
: async downloading scripts (download in order), execute after parsing HTML is doneasync
: async downloading scripts (downloading might be out of order), execute after downloading is done (will pause parsing HTML)
DOM Manipulation
Node (like root interface) -> Document -> Element
Selector
You can use the following selector on document
or element
.
NOTE you cannot use pure number in your selector
The selector attributes should be CSS identifiers or strings. So you cannot use number there!
var a = document.querySelector('a[data-a="1"]');
Select the first or null ($(selector)
in DevTools):
const myElement = document.querySelector('#foo > div.bar input[name="login"]')
Returns the first descendant
Element
using DFS + Pre-order traversalIt's not live, compare to
getElementsByTagName()
Select all matching ($$(selector)
in DevTools):
const myElements = document.querySelectorAll('.bar')
Returns
NodeList
iterate:
for .. of
orforEach
or.item(i)
Compare/Match:
node.contains(element)
e.target.nodeName == "LI"
e.target.matches('input')
(Element.matches)
Traverse:
traverse parents:
element.closest('selector')
how to polyfill? see MDN
Others: using above is recommended.
Attributes
Generally, you can do:
element.getAttribute('id')
orelement.getAttribute('data-parent')
element.setAttribute('tabindex', 3);
element.id
js: it's accessible (read/write) from js by the
dataset
property. Note dashes are converted to camelCase)css:
attr()
CSS
On make item invisible as well as clickable: https://css-tricks.com/snippets/css/toggle-visibility-when-hiding-elements/
Element CRUD
Update content
Observe Changes
The MutationObserver
interface provides the ability to watch for changes being made to the DOM tree.
You can observe changes (child, attributes, style, etc) and pause in dev tools:
Common Functions
BOM
Reload window:
location.reload();
Scroll to top:
window.scrollTo(0, 0);
Don't use onclick
: single property, essentially override it.
Event CRUD
Override Default Event
preventDefault()
stop default handling, it'll still propagatestopPropagation()
stop bubbling upstopImmediatePropagation()
stop handling in current layer, stop passing to other event handlers: If several listeners are attached to the same element for the same event type, they are called in order in which they have been added. If during one such call, event.stopImmediatePropagation() is called, no remaining listeners will be called.
e.target vs e.currentTarget:
e.target
identifies the element on which the event occurrede.currentTarget
always refer to the the element to which the event handler has been attached
this
this
usually points to the DOM element where the handler is bound.
NOTE if you add event using arrow function then it's
document
instead of the element!
How to trigger event manually:
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
How to perform click? element.click()
Keyboard/Mouse events:
See examples from: https://eloquentjavascript.net/15_event.html
Custom events
interface for any custom event:
custom implementation of EventEmitter
Event Delegation
Use one event handler to handle all children events
Event delegation can also be used to add behavior to any element (with data-attr):
Last updated