前端入门:DOM 基础总结
1.1DOM 概念
DOM 全称为 Document Object Model,即文档对象模型。它是一套用来管理控制 html 文档的规则。
1.2 节点类型
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
1: 元素节点
2: 属性节点
3: 文本节点
6: 注释节点
9: 文档节点, document
11: 文档片断节点
document 节点又被叫做 document 对象。每个载入浏览器的 HTML 文档都会成为 document 对象。document 是 html 文档的根节点,每张网页都有自己的 document 节点。window.document 属性就指向这个节点。也就是说只要浏览器开始载入 HTML 文档,这个节点对象就存在了,可以直接调用。
1.3 获取 dom 元素
1.3.1 通过标签名获取元素,返回一个类数组(HTMLCollection)
//返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)node.getElementsByTagName("tagName");//标签获取元素var li = document.getElementsByTagName("li");
1.3.2 通过 id 获取页面元素
//获取带有指定 id 的节点(元素)document.getElementById("idName");//id获取元素var header = document.getElementById("header");
1.3.3 通过 class 名字获取页面元素,返回一个类数组
//返回包含带有指定类名的所有元素的节点列表document.getElementsByClassName("className");
注意:getElementsByClassName() 在 Internet Explorer 5,6,7,8 中无效。
1.3.4 通过 name 名字获取页面元素
//返回包含带有指定名的所有元素的节点列表var first = document.getElementsByName("first");
1.3.5 通过 CSS 选择符方式获取页面元素
//querySelector:返回符合条件的第一个document.querySelector("selector");//返回符合条件的全部document.querySelectorAll("selector");//querySelector:返回符合条件的第一个var str = document.querySelector("li");//全部返回,每个li都是一个对象var str1 = document.querySelectorAll("li");
1.4 NodeList 与 HTMLCollection 区别
node.childNodes 结果返回类型是 NodeList,
node.children 结果返回类型是 HTMLCollection
node(document 或者其他不同节点).getElementsByXXX 结果返回类型是 HTMLCollection
唯一要注意的是 querySelectorAll 返回的是 NodeList ,但是实际上是元素集合,并且是静态的
1.4.1 NodeList 节点集合
NodeList 节点集合可以理解为 HTMLCollection 元素集合的父集,它包含了 DOM 对象的所有节点
遍历节点
因为 NodeList 对象是一个类似数组的对象, 且它自带了一个 forEach() 方法, 因此可以使用 forEach() 遍历, 它的用法和 Array 里面的 forEach() 是完全一样的.语法:
document.querySelectorAll("li").forEach((item, i, obj) { console.log(i + " - " + item.textContent);});
这里的 item 为当前元素, i 为索引, obj 为整个 NodeList.
1.4.2 HTMLCollection 元素集合
HTMLCollection 元素集合可以理解为 NodeList 节点集合的子集,它只包括了元素集合。HTMLCollection 和 NodeList 一样包含了查询得到的 html 元素,length 属性和 item 方法,但没有 NodeList 的 entries, forEach, keys, values 这四个方法。
HTMLCollection:类数组
键名: 由 0 开始的正整数
有一个 length 属性,表示数量
如何遍历
var parent = document.querySelector(".parent");for (var i = 0; i < parent.childElementCount; i++) { console.log(parent.children.item(i));}
1.5 事件添加方式
1.5.1 给 html 元素绑定事件属性
<button onclick="show(this)">按钮</button><script> var cl = console.log.bind(console); //1. 给html元素绑定事件属性 function show(ele) { var text = ele.innerText; alert(text); }</script>
1.5.2 给 html 元素添加属性
<button>按钮</button><script> var btn = document.querySelector("button"); btn.onclick = function () { alert(this.nodeName); };</script>
1.5.3 监听器
<button>按钮</button><script> var btn = document.querySelector("button"); // btn.addEventListener(事件类型, 事件回调函数, 传递机制) btn.addEventListener( "click", function () { alert(this.innerText); }, // false: 冒泡阶段触发 false );</script>
1.5.4 事件派发
<button>按钮</button><script> var btn = document.querySelector("button"); btn.addEventListener( "click", function () { alert(this.innerText); }, false ); // 创建一个事件对象 var ev = new Event("click"); // 不用点击,也会自动的触发点击事件 btn.dispatchEvent(ev);</script>
1.6 事件委托/代理
JavaScript 高级程序设计:事件委托还有一个名字叫事件代理,事件委托就是利用事件冒泡,制定一个时间处理程序,就可以管理某一类型的所有事件。
案例:给每一个 li 项目添加一个点击事件
<ul> <li>item1</li> <li>item2</li> <li>item3</li> <li>item4</li> <li>item5</li></ul><script> 事件委托/代理: 子元素上的事件会冒泡到父元素上的同名事件上触发 document.querySelector("ul").addEventListener("click", function (ev) { alert(123456); });</script>
1.7 时间的捕获和冒泡
1.8 总结
在 JavaScript 中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,性能优化的主要思想之一就是减少 DOM 操作。每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率越大,100 个 li 就要占用 100 个内存空间。如果要用事件委托,就会将所有的操作放到 js 程序里面,只对它的父级(如果只有一个父级)这一个对象进行操作,与 dom 的操作就只需要交互一次,这样就能大大的减少与 dom 的交互次数,提高性能;