JavaScript & DOM
JS intro
- init to make webpages alive .., run on platforms with JS engine (in browser aka “JS VM”, e.g. “V8” in Chrome & Opera) ..
- JS in HTML:
<script>..</script>&<script src=..></script>.. - in-browser JS restrictions …
DOM tree
- repre HTML/XML doc structure .. (inc
<!DOCTYPE HTML>..), built when pages loading .. (auto-correction ..) - rooted at
document(repre the whole doc..) —document.documentElement/.head /.body.. - interact DOM elem in console ..
DOM node class hierarchy ..
- Node: Element, Text, Comment, Document (e.g.
HTMLDocumentinstancedocument..) - type check:
node.nodeName/elem.tagName..
HTML Attr & JS Prop
- HTML-attr: case-insensitive & value: str ..
- HTML
hiddenattr —style="display:none..
- HTML
- DOM prop: case-sensitive & value: any type ..
- access attr by elem methods ..
- prop-attr sync .. & prop-attr type diff ..
- customized attr ..: pass data to JS || “mark” HTML-elem for JS
- naming:
data-*, access:dataset.xxx(mtp-word camelCase)
- naming:
DOM modification
Node Creation: document.createElement(tag: str).., elem.cloneNode(..) ..
Node Selection ..
elem.querySelector*(css: str)— css:'tag[attr]'.. & ..- other query methods ..
- nav props (child, parent, sibling, read-only) ..
- table props ..
Node modification
Content
elem.innerHTML..- innerHTML += xxx: replace instead addition (resrc reload, selection & input rmed)
- insert
<script>by innerHTML: inserted but not executed - elem.outerHTML = innerHTML + elem itself ..
- write to elem.outerHTML: replace node in DOM but not change elem itself (var still ref to the old value) — query again
elem.textContent: inner text without tags, insert as text (safer theninnerHTML)Text/Comment.data: text/cmt content of the node (similar to nodeValue prop) ..- task: Count descendants, Create a calendar, Sort the table
Style
css class style (prefer ..)
- read class style:
getComputedStyle(elem, ..).<camelCaseProp>: str with unit (of resolved value), e.g. “20px” .. - set class:
elem.className(whole replace) /elem.classList(single class) ..
style-attr style: elem.style.<camelCaseProp>: str with unit, e.g. “100px”, writable ..
- rm style :
elem.style.xxx = '' - full rewrite
elem.style.cssText = xxx||setAttribute('style', cssText)..
Size, coords & scroll
geometry props: return num (in “px”) ..
- Size props:
offset*,client*… - scrolled props:
scroll*…, …1
2
3
4elem.style.height = `${elem.scrollHeight}px`; // expand elem to full height
elem.scrollTop = elem.scrollHeight; // auto-scroll up [Events mouseover/mouseout, relatedTarget]
elem.scrollTop = 0 / Infinity // scroll to top/bottom - coords props ..:
clientX/Y(rel to win, css position: fixed) &pageX/Y(rel to doc, css position: absolute) .., ..document.elementFromPoint(clientX, clientY): most nested elem, null if out of win ..
- get coords:
- tasks: Find win coords of the field, Position the note inside (absolute)
Notes
- text overflow — padding-bottom area may filled with text ..
- for elem width/height/distance, use geometry prop (e.g. clientWidth) instead getComputedStyle() .., ..
- get win size:
document.documentElement.clientWidth/H(without sbar) vswindow.innerWeight/H(inc sbar) .. - get doc size (with scroll out part) ..
Node insert, move & rm
- insert (replace) as text:
node.append/prepend/before/after/replaceWith(..)..- move nodes by inserting existing one (auto rm from old place) ..
- insert as HTML:
elem.insertAdjacentHTML(..).. - removal:
node.remove().. - the old insert/rm methods .. &
document.write(html: str)..: call when onload to write html into page “right here and now” (call af load replace page content)
Event handling
Event & event obj
events list …
event happen -> browser create event-obj (puts details into it) & pass as arg to event handler ..
Event obj: e.type (e.g. “click”) ..
Event Bubbling & event delegation pattern
- 3 Event phase (Capturing, Target, Bubbling —
e.eventPhase..) - event delegation (handle event on container for mtp elems) ..
e.target,e.currentTarget..- stop bubbling …
- tasks: Hide messages with delegation, toogle tree menu, Sortable table, Tooltip behavior
script-gen event ..
- construct .. & .., dispatch ..
- diff user event & script-gen event:
e.isTrusted.. - custom event &
detailprop .., ..
Event Processing Queue: Asycnly & Syncly ..
Event handler: fn(e)
add/rm Event handler
elem.addEventListener(e-type, handler, ..)..- HTML attr
on<event>="fn-body".. || DOM propelem.on<event> = fn.., e.g. onclick
Others
thisin handler: e.currentTarget .. & ..elem.setAttribute('on<event>', handler)not work for event handler ..- Tasks: Move the ball across the field, Create a sliding menu, Add a closing button, Carousel
Prevent default actions
e.preventDefault() on handler || on<event> handler return false ..
e.defaultPrevented(status check): true (means the event is handled somewhere) .. &elem.dispatchEvent(event)return false ..passive: trueoption ofaddEventListener: signals that the handler not to call preventDefault() why needed?- default browser action list ..
- Tasks: Why “return false” doesn’t work?, Image gallery
Mouse Event
- events list …
- mouse coords:
e.clientX/Y, e.pageX/Y.., mouse btn:e.button(=0 left-btn, =1 middle, =2 right-btn) .. - mouse event also inc info of modifier keys:
e.shiftKey/altKey/ctrlKey/metaKey(Mac): bool (true if pressed) .. - disable selection (on dblclick) & copy:
onmousedown/oncopy return false..
Mouse & Pointer Event
mousemove .., mouseover/out event & e.relatedTarget (diff with mouseenter/leave) ..
- event delegation example ..
- task: “Smart” tooltip (tooltip style)
- impl by mouse events: overall algorithm .., pointer correct positioning .., drappable elem hightlight ..
- draggable elem always above other elem when dragging & mouse event only happen on the top elem, so eh on other elem not work, can fix by
1
2
3draggble.hidden = true;
let elemBelow = document.elementFromPoint(e.clientX, event.clientY);
draggble.hidden = false;- task: Slider, Drag superheroes around the field (not checked yet)
- draggable elem always above other elem when dragging & mouse event only happen on the top elem, so eh on other elem not work, can fix by
- Pointer Event: handling mouse, touch and pen events simultaneously, with a single piece of code ..
Scroll Event
scrollevent on elem & win ..- task: Endless page, Up/down button, Load visible images
Keyboard Event
keydown, keyup ..
-
e.code(physical key loc, e.g “KeyZ”, “ShiftLeft”) vsevent.key(meaning of key, ie. char inputted, e.g. “z” || “Z”) .. - key repeat: key pressed for a long enough time ..
- task: Extended hotkeys
Form Ctrl
- named collection:
document.forms&form/fieldset.elements(fieldset as subform) .. - back-ref:
elem.form.. - Form elements: input/textarea, select and option ..
Focusing Event
focus / blur event .. & elem.focus/blur() ..
- event not bubble (but capturable) — bubble version
focusin/focusoutevent (handler assign byelem.addEventListener)
Others
- get current focused elem:
document.activeElement.. — css:focus.. autofocusattr ..- enable any elem focusable:
tabindexattr ||elem.tabindex.. - input validate attr:
required,pattern…
task: Editable div, Edit TD on click, Keyboard-driven mouse
Data update events
changeevent: on finish change, e.g. text-input elem blur, select-opt changes ..inputevent: on any value change ..cut/copy/pasteevent …
Form submit event
submit event on form (sent data to server):
- trigger on press “Enter” on input field => trigger click on input[type=submit] ..
- submit form manually:
form.submit(): (submitevent not generated) - tasks: Modal form
Doc & resrc loading
Page load events
document.DOMContentLoaded: HTML & DOM tree ready, form autofill ..window.load: external resrc (css, img) loaded (img size known) ..window.beforeunload/unload: user leaving this page: nav to other pages/close win ..window.onbeforeunloadreturn false / non-empty str: cancel the event (prevent default?) & show the str as msg e.g. “change not save, sure to leave?” — answer negative block page-nav? ..
Others
document.readState: “loading”, “interactive” , “complete” — the old document.readystatechange ..- Whole process …
External script attr: async, defer
Both only for external script (ignored if no src attr) .., .. and load not-block (load script in bg)
async: run in load-1st order ..- Dynamic scripts (gen by JS) load af insert to the doc ..
defer: run (in doc order) when DOM ready (but bf DOMContentLoaded event) ..
Resrc loading event
Most resrcs start loading when added to the doc, except <img> (load when gets src & cached ..)