JavaScript Client-Side API
iRef => How JavaScript is Running on the Client Side?
网页渲染.md
DOM
DOM Actually, Document对象并非独立的,它是一个巨大的API中的核心对象,也就是文档对象模型(Document Object Model, DOM),它代表和操作文档的内容。
DOM Level
- Level1:DOM Core 以及 DOM HTML 构成。DOM 核心定义了如何映射基于 XML 的文档结构,以便简化对其文档中任意部分的访问和操作。DOM HTML 模块则在 DOM 的核心基础上加以扩展,实现了针对 HTML 的对象和方法。
- Level2:扩充了一系列的鼠标和用户界面事件、范围、遍历 DOM 的方法等细分模块,同时添加了针对 CSS 的可编程接口。
- DOM Views:定义了如何跟踪不同的文档视图接口
- DOM Events:定义了事件和事件处理的接口
- DOM Style:定义了基于 CSS 为元素的样式接口
- DOM Traversal and Range:定义了遍历和操作文档树的接口
- Level3:进一步扩展 DOM,引入了统一方式加载和保存文档的方法模块、DOM 验证模块,支持 XML1.0 规范
- 其它 DOM 标准:SVG、MathML、SMIL 等
Node Type
// Node Type
Node = window.Node
Node.ELEMENT_NODE(1)
Node.ATTRIBUTE_NODE(2)
Node.TEXT_NODE(3)
Node.CDATA_SECTION_NODE(4) // wtf?
Node.ENTITY_REFERENCE_NODE(5)
Node.ENTITY_NODE(6)
Node.PROCESSING_INSTRUCTION_NODE(7)
Node.COMMENT_NODE(8)
Node.DOCUMENT_NODE(9)
Node.DOCUMENT_TYPE_NODE(10)
// 是一种实际文档之中并不存在的一种节点:它代表一系列没有常规父节点的节点
Node.DOCUMENT_FRAGMENT_NODE(11)
Node.NOTATION_NODE(12)
node.nodeType
node.nodeName
node.nodeValue
// Node List
var firstChild = someNode.childNodes[0]
var secondChild = someNode.childNodes.item(1)
// 作为节点的 Node
node.parentNode
node.childNodes
node.firstchild
node.lastChild
node.nextSibling
node.previousSibling
node.hasChildNodes() // true or false
node.appendChild();
node.insertBefore(newNode, parentNode);
node.removeChild(node);
node.replaceChild(ReplacedNode);
node.cloneNode();
Document Type
document.documentElement
document.doctype
document.title
document.URL
document.referrer
document.domain
// DOM 查询和遍历
document.getElementById();
document.getElementsByName();
document.getElementsByTagName();
document.getElementsByClassName();
document.querySelector();
document.querySelectorAll(); // 并非实时的 NodeList 对象
document.anchors
document.applets
document.forms
document.images
document.links
document.scripts
document.styleSheets
document.styleSheets[0].cssRules[0].style.cssText
styleSheet.insertRule() / deleteRule()
// DOM 修改
document.write()
document.writeln() // 会在字符串末尾加上 \n
document.open()
document.close()
document.createElement();
document.createComment();
document.createTextNode();
document.createAttribute()
document.createDocumentFragment();
Element Type
element.nodeName
element.tagName
ele.className
ele.title
ele.lang
ele.dir
ele.style
ele.style[styleNmae] = 'xxxx';
ele.style.cssText = 'xxxx';
window.getComputedStyle(element, [pseudoElt])
ele.classList.remove()
ele.classList.add()
ele.classList.toggle()
ele.classList.contains()
ele.attributes // Dynamic set like NodeList
ele.chrildren[0]
ele.contains()
HTMLAchorElement
HTMLAppletElement
HTMLHeadingElement
HTMLTableColElement
...
element.innerHTML = '<div></div>'
element.outerHTML = ''
element.innerText
element.outerText
// 元素几何尺寸的查询
element.getBoundingClientRect();
element.getClientRects();
// 判定元素在某点
element.elementFromPoint();
// CSS 文档操作
element.style.cssProps = '23px';
document.styleSheets[i].disabled = true;
element.getAttribute('style');
element.setAttribute('style', props);
element.removeAttribute('style')
element.getComputedSytle();
element.getPropertyValue();
Text Type
textNode.nodeType === 3 // true
textNode.parentNode
textNode.appendData(text)
textNode.deleteData(offset, count)
textNode.insertData(offset, text)
textNode.replaceData(offset, count, text)
textNode.splitText(offset)
textNode.substringData(offset, count)
textNode.nodeValue.length
element.normalize() // merge the textNode
- TextRange
// 定位输入的游标
const setCaretPosition = (input, index) => {
if (!input) {
return false;
}
if ('selectionStart' in input) {
input.selectionStart = index;
input.selectionEnd = index;
input.focus();
} else if (input.createTextRange) {
const range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', index);
range.moveStart('character', index);
range.select();
}
return false;
};
Other Types of Nodes
// Comment Type
commentNode.data // comment content
document.createComment('this is a comment')
// CDATASection Type
// Based on XML Document, represent the range of CDATA which is a
// Child Class of Text
// DocumentType Type: concerned with doctype of the current document
DOM Events
- 理解JS的事件系统:单线程的,非阻塞式 I/O ,EventLoop 事件机制
- 理解异步函数的范式
- 异步函数:
setTimeout()
,setInterval()
- 间或异步函数(时而同步,时而不同步)e.g.
$()
- 缓存异步函数:缓存后是同步的,非缓存之前是异步的
- 异步函数:
- 事件代理
- 事件与冒泡,从高层次代理,通过
e.target
捕获相应的元素
- 事件与冒泡,从高层次代理,通过
- 分布式事件
- 参考JS设计模式中:Pub/Sub 模式以及 Promise 模式。Promise 对象和 Deferred 对象。
setTimeout(function() {console.log(1);}, 1);
for (var i = 0; i < 20000000; i++) console.log(i);
// output: 1 2 3 .. 20000000 1
DOM 事件体系
- 事件的三个阶段(捕获阶段、触发阶段、冒泡阶段)
- 触发过程中会创建
Event
对象,该对象有一系列描述事件的属性和存储 DOM 的相关引用 - 阻止冒泡 / 阻止浏览器默认行为:
stopPropagation() / preventDefault()
模拟事件
document.createEvent()
document.dispatchEvent()
DOM 事件处理
- DOM0级的事件回调函数的
this
指向事件触发的那个元素。 - DOM2级事件处理增加了
add/removeEventListener()
的方法,支持type
以及handler
以及catch/bubble
的参数。 - IE 对事件流的支持:
attach/detachEvent()
但注意,此时的this
指向全局作用域window
Event 对象
e.bubbles
e.cancelable
e.currentTarget
e.defaultPrevented
e.detail
e.eventPhase
e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation() // DOM Level 3
e.target
e.type
e.trusted
e.view // return current window object
// IE Special
e.cancelBabel // boolean
e.returnValue // boolean
e.srcElement // e.target
// Special Event
e.shift/alt/meta/ctrlKey // onclick ...
e.relatedTarget // onmouseover/out
e.wheelDelta
事件类型
- UI 事件
load
unload
abort
error
select
resize
scroll
- 焦点事件
focus
blur
- 鼠标事件
- 注意区分:
clientX
pageX
screenX
offsetX
- 注意区分:
- 滚轮事件
- 文本事件
- 键盘事件
- 复合事件:IME相关
- 变动事件 Mutation
- 变动名称事件 DOM3 event
DOMSubtreeModiied
DOMNodeInserted
DOMNodeRemoved
DOMNodeInsertedIntoDocument
DOMNodeRemovedFromDocument
DOMAttrModified
DOMCharacterDataModified
- HTML5
oncontextmenu
DOMContentLoaded
readystatechange
pageshow/hide
hashchange
移动设备事件
orientationchange
deviceorientation
三轴取值devicemotion
手势事件
touchstart/end/move/cancel
touches
targetTouch
targetTouches
- `gesturestart/end/change
Advanced Features
- NodeIterator
- TreeWalker
- Document Range