Dom:
文档对象模型 – 能够操作一切结构化文档的通用api
- 核心Dom – API繁琐,功能很全: 增删改查
- HTMLDom – 基于核心Dom, 扩展专门操作HTML内容的API,简单易用,主要重点简化了修改的操作
核心Dom:
Dom Tree: 网页加载内存的时候,会先创建一个document对象,指代当前页面中的所有内容: 元素,文本,属性,注释等,都叫做节点对象。
document作为DomTree根节点存在的,所有的子节点都是document对象的子节点(Node)节点对象的类型:
- document对象: 文档类型(Document)
- 元素节点: 元素类型(Element)
- 属性节点: 属性类型(Attr)
- 文本节点: 文本类型(Text)
节点类型的三个通用属性:
nodeType:获得当前节点的类型,返回类型为数值
ELEMENT_NODE : 1
ATTRIBUTE_NODE: 2
TEXT_NODE: 3
DOCUMENT_NODE: 9 – 代表整个文档
DocumentType_NODE: 10 – 文档定义声明类型(<! DOCTYPE HTML>)nodeName: 获取当前节点的名称
元素节点: * 全大写字母*的标签名
文本节点: #test
文档节点: #document
应用场景:判断区分不同元素节点时使用nodeValue:获取当前节点的值,对元素节点无效
元素节点: null
文本节点: 返回文本内容
DomTree:
- 父子关系:parentNode childNodes firstChild lastChild
- 兄弟关系: previousSibing nextSibling
注意: 除了parentNode以外,所有的API都会受到看不到的空字符干扰
集合
NodeList集合 – 类数组对象
分为动态集合和静态集合:
- document.querySelectorAll()(静态集合)
- childNodes (动态集合)
动态集合是当dom树中增加或删除一个子节点的时候,会实时更新集合内得数据,会影响集合中的length属性。
遍历节点树(面试/算法):深度优先算法 - 递归调用;
算法: 深度优先原则,优先遍历下级节点,直到该节点结束时,才返回并更换另一个分支继续遍历
function fun(curr){
console.log(
curr.nodeType != 1 &&
curr.nodeType != 9 &&
curr.nodeType != 10 ? curr.nodeValue : curr.nodeName
)
// 如果curr有子节点,就遍历curr下所有的子节点
let children = curr.childNodes;
if(children){
// 遍历找到的所有子节点,并把当前子节点当作父节点向下遍历
for(var i = 0,len = children.length; i < len; i++){
fun(children[i]);
}
}
}
window.onload = function(){
fun(document);
}
arguments.callee
指代当前的函数对象引用,一般用于函数递归,只要是递归,就优先使用arguments.callee
由此可以改进上面代码
window.onload = function(){
(function(curr){
console.log(
curr.nodeType != 1 &&
curr.nodeType != 9 &&
curr.nodeType != 10 ? curr.nodeValue : curr.nodeName
)
// 如果curr有子节点,就遍历curr下所有的子节点
let children = curr.childNodes;
if(children){
// 遍历找到的所有子节点,并把当前子节点当作父节点向下遍历
for(var i = 0,len = children.length; i < len; i++){
arguments.callee(children[i])
}
}
})(document);
}
案例面试题
var emp = {
fun: function(){
var sum = 0;
for(let i = 0;i < arguments.length && arguments[0] > 0; i++){
sum += arguments[i] + arguments.callee(--arguments[i]);
// 3 + arguments.callee(2) -> 3
// 2 + arguments.callee(1) -> 1
// 1 + arguments.callee(0) -> 0
// 2 + arguments.callee(1) -> 1
// 1 + arguments.callee(0) -> 0
// 1 + arguments.callee(0) -> 0
}
return sum;
}
}
console.log(emp.fun(3,2,1)); // 10