DOM

HTML和XML里有很多节点。
最外层的称作文档节点(文档元素),也是每个文档的根节点。在HTML中就是html这个元素。
一共有12中元素节点类型。

Node类型

最基本的节点类型是 Node,用于抽象地表示文档中一个独立的部分;所有其他类型都继承自Node。
DOM基础 - 图1

Element类型

从本质上说,所有 NodeList 对象都是在访问 DOM 文档时实时运行的查询。下列代码会导致无限循环:

  1. var divs = document.getElementsByTagName("div"), // 性能问题
  2. i,
  3. div;
  4. for (i = 0; i < divs.length; i++) {
  5. div = document.createElement("div");
  6. document.body.appendChild(div);
  7. }

一般来说,应该尽量减少访问 NodeList 的次数。因为每次访问 NodeList,都会运行一次基于文档的查询。应考虑将其值缓存起来。

  • querySelector()
  • querySelectorAll():返回NodeList 的实例。底层实现则类似于一组元素的快照,而非动态查询。 可避免性能问题。
  • getElementsByClassName()方法:返回带有指定类的所有元素的 NodeList。性能问题。 ```javascript //取得所有类中包含”username”和”current”的元素,类名的先后顺序无所谓 var allCurrentUsernames = document.getElementsByClassName(“username current”);

//取得 ID 为”myDiv”的元素中带有类名”selected”的所有元素 var selected = document.getElementById(“myDiv”).getElementsByClassName(“selected”);

  1. - classList 属性<br />在操作类名时,需要通过 className 属性添加、删除和替换类名。
  2. ```javascript
  3. <div class="bd user disabled">...</div>
  4. //删除"user"类
  5. //首先,取得类名字符串并拆分成数组
  6. var classNames = div.className.split(/\s+/);
  7. //找到要删的类名
  8. var pos = -1,
  9. i,
  10. len;
  11. for (i=0, len=classNames.length; i < len; i++){
  12. if (classNames[i] == "user"){
  13. pos = i;
  14. break;
  15. }
  16. }
  17. //删除类名
  18. classNames.splice(i,1);
  19. //把剩下的类名拼成字符串并重新设置
  20. div.className = classNames.join(" ");

HTMLCollection和NodeList

共同点:

  • 都是类数组对象,都有length属性
  • 都有共同的方法:item,可以通过item(index)或者item(id)来访问返回结果中的元素
  • 都是实时变动的(live),document上的更改会反映到相关对象上(例外:document.querySelectorAll返回的NodeList不是实时的)

    不同点:

  • NodeList可以包含任何节点类型,HTMLCollection只包含元素节点(elementNode),elementNode就是HTML中的标签

  • HTMLCollection比NodeList多一项方法:namedItem,可以通过传递id或name属性来获取节点信息

    事件委托

    事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

    为什么要用事件委托

    一般来说,dom 需要有事件处理程序,如果有100个li节点,都要一一设定事件处理程序。而事件处理程序的数量和页面整体运行性能相关,用事件委托会将所有操作放到JS程序里面,与DOM操作只需要交互一次,大大减少了事件处理程序的数量。

    事件委托的原理

    原理是通过事件冒泡机制实现的。事件冒泡从里向外传播事件。如结构为div>ul>li>a,给div标签添加点击事件监听函数,当点击a标签时,事件往外传播被div的监听函数接收到,从而触发,即事件委托(给其父级代为处理)。

    实现

  • 没有事件委托时:

    1. <ul>
    2. <li>111</li>
    3. <li>222</li>
    4. <li>333</li>
    5. <li>444</li>
    6. </ul>
    1. window.onload = function(){
    2. var oUl = document.getElementById("ul1");
    3. var aLi = oUl.getElementsByTagName('li');
    4. for(var i=0;i<aLi.length;i++){
    5. aLi[i].onclick = function(){
    6. alert(123);
    7. }
    8. }
    9. }
  • 事件委托时:

    1. window.onload = function(){
    2. var oUl = document.getElementById("ul1");
    3. oUl.onclick = function(){
    4. alert(123);
    5. }
    6. }