博客列表 >DOM操作:分析NodeList与HTMLCollectio区别、事件

DOM操作:分析NodeList与HTMLCollectio区别、事件

emy
emy原创
2020年06月07日 00:03:011004浏览

一、DOM操作

1-NodeList:
a-NodeList是一个节点的集合(既可以包含元素和其他节点),在DOM中,节点的类型总共有12种,通过判断节点的nodeType来判断节点的类型。
b-NodeList对象有个length属性和item()方法,length表示所获得的NodeList对象的节点个数,这里还是要强调的是节点,而item()可以传入一个索引来访问Nodelist中相应索引的元素。
c- js 节点有11种类型,但是与html相关的只有6个

类型名称常数值
元素节点1
属性节点2
文本节点3
实体名称节点6
文档节点9
文档片段节点11
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>遍历元素节点</title>
  </head>
  <body>
    <ul>
      <li>item1</li>
      <li>item2</li>
      <li>item3</li>
      <li>item4</li>
      <li>item5</li>
    </ul>
  </body>
  <script>
    var cl = console.log.bind(console);

    var ul = document.querySelector("ul");
    cl(ul);
    // 子节点
    cl(ul.childNodes);
    cl(ul.childNodes.length);
    cl(ul.childNodes[2]);
    // js节点    
    cl(ul.childNodes[0]);
    cl(ul.childNodes[0].nodeType);
    cl(ul.childNodes[1].nodeValue);
    cl(ul.childNodes[1].nodeName);
    // 最后一个
    cl(ul.childNodes[ul.childNodes.length - 1]);
    cl(ul.childNodes[ul.childNodes.length - 2].nodeName);
    // 遍历
    var eles = [];
    ul.childNodes.forEach(function (item) {
      // 只返回类型为1的元素节点
      if (item.nodeType === 1) this.push(item);
    }, eles);
    cl(eles);
    //获取第一个子节点
    cl(ul.firstChild);
    // cl(ul.childNodes[0]);
    cl(ul.childNodes[ul.childNodes.length - 1]);
    // 最后一个子节点
    cl(ul.lastChild);
    // 前一个兄弟节点
    cl(ul.lastChild.previousSibling);
    // 后一个兄弟节点
    cl(ul.firstChild.nextSibling);
  </script>
</html>

QQ截图20200606233927.jpg

2-HTMLCollection

a-HTMLCollection是元素集合,它和NodeList很像,有length属性来表示HTMLCollection对象的长度,也可以通过elements.item()传入元素索引来访问。
b-HTMLCollection的集合和NodeList对象一样也是动态的,他们获取的都是节点或元素集合的一个引用。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>遍历元素节点</title>
  </head>
  <body>
    <ul>
      <li>item1</li>
      <li>item2</li>
      <li>item3</li>
      <li>item4</li>
      <li>item5</li>
    </ul>
  </body>
  <script>
    var cl = console.log.bind(console);

    var ul = document.querySelector("ul");

    // children
    // childNodes: 返回所有节点,包括元素,文本...
    cl(ul.childNodes);
    // children: 只返回元素
    cl(ul.children);
    cl(ul.children.length);
    cl(ul.childElementCount);
    // 第一个元素
    cl(ul.firstElementChild);
    // 最后一个
    cl(ul.lastElementChild);
    // 任何一个
    cl(ul.children[2]);
    // 前一个兄弟
    cl(ul.children[2].previousElementSibling);
    //后一个兄弟
    cl(ul.children[3].nextElementSibling);
    // HTMLCollection没有forEach
    cl("-----------");
    for (var i = 0; i < ul.childElementCount; i++) {
      cl(ul.children.item(i));
    }
  </script>
</html>

QQ截图20200606234304.jpg
3-NodeList和HTMLCollection的区别:

NodeList:文档节点集合
HTMLCollection: 文档元素集合
HTMLCollection相当于是NodeList中type=1的节点集合
二、事件

1-事件添加方式

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件添加方式</title>
  </head>
  <body>
    <button onclick="var text=this.innerText;alert(text);">按钮1</button>
    <button onclick="show(this)">按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>
  </body>
  <script>
    var cl = console.log.bind(console);
    //1. 给html元素绑定事件属性
    function show(ele) {
      var text = ele.innerText;
      alert(text);
    }
    // 2. 给html元素添加属性
    var btn3 = document.querySelector("button:nth-of-type(3)");
    btn3.onclick = function () {
      alert(this.nodeName);
    };
    // 3. 监听器
    var btn4 = document.querySelector("button:nth-of-type(4)");
    // btn4.addEventListener(事件类型, 事件回调函数, 传递机制)
    btn4.addEventListener(
      "click",
      function () {
        alert(this.innerText);
      },
      // false: 冒泡阶段触发
      false
    );

    // 4. 事件派发
    var btn5 = document.querySelector("button:last-of-type");
    btn5.addEventListener(
      "click",
      function () {
        alert(this.innerText);
      },
      false
    );
    // 创建一个事件对象
    var ev = new Event("click");
    // 不用点击,也会自动的触发点击事件
    btn5.dispatchEvent(ev);
  </script>
</html

QQ截图20200606234756.jpg

2-事件委托/代理

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件传递与事件委托/代理</title>
  </head>
  <body>
    <div class="first">
      <div class="second">
        <div class="three">事件传递</div>
      </div>
    </div>
  </body>
  <script>
    // 事件的捕获与冒泡
    var cl = console.log.bind(console);

    var first = document.querySelector(".first");
    var second = document.querySelector(".second");
    var three = document.querySelector(".three");

    // true: 捕获阶段触发事件
    first.addEventListener(
      "click",
      function (ev) {
        // ev: 事件对象
        // ev.type: 事件类型
        // ev.target: 触发事件的元素
        // ev.currentTarget: 绑定事件的元素
        // cl(ev.target.classList.item(0));
        cl(
          "捕获阶段:" + "触发: " + ev.target.classList.item(0),
          "绑定:" + ev.currentTarget.classList.item(0)
        );
      },
      true
    );

    second.addEventListener(
      "click",
      function (ev) {
        cl(
          "捕获阶段:" + "触发: " + ev.target.classList.item(0),
          "绑定:" + ev.currentTarget.classList.item(0)
        );
      },
      true
    );

    three.addEventListener(
      "click",
      function (ev) {
        cl(
          "捕获阶段:" + "触发: " + ev.target.classList.item(0),
          "绑定:" + ev.currentTarget.classList.item(0)
        );
      },
      true
    );

    // false: 冒泡阶段触发事件
    first.addEventListener(
      "click",
      function (ev) {
        // ev: 事件对象
        // ev.type: 事件类型
        // ev.target: 触发事件的元素
        // ev.currentTarget: 绑定事件的元素
        // cl(ev.target.classList.item(0));
        cl(
          "冒泡阶段:" + "触发: " + ev.target.classList.item(0),
          "绑定:" + ev.currentTarget.classList.item(0)
        );
      },
      false
    );

    second.addEventListener(
      "click",
      function (ev) {
        cl(
          "冒泡阶段:" + "触发: " + ev.target.classList.item(0),
          "绑定:" + ev.currentTarget.classList.item(0)
        );
      },
      false
    );

    three.addEventListener(
      "click",
      function (ev) {
        cl(
          "冒泡阶段:" + "触发: " + ev.target.classList.item(0),
          "绑定:" + ev.currentTarget.classList.item(0)
        );
      },
      false
    );
  </script>

  <!-- 冒泡实现事件的委托/代理 -->
  <ul>
    <li>item1</li>
    <li>item2</li>
    <li>item3</li>
    <li>item4</li>
    <li>item5</li>
  </ul>
  <script>
    document.querySelectorAll("ul li").forEach(function (item) {
      item.addEventListener("click", function (ev) {
        cl(this === ev.target);
        cl("当前触发事件的元素是:", this);
      });
    });

    // 事件委托/代理: 子元素上的事件会冒泡到父元素上的同名事件上触发
    // document.querySelector("ul").addEventListener("click", function (ev) {
    //   //   cl(ev.target);
    //   //   cl(ev.currentTarget);
    //   //   cl(this === ev.currentTarget);
    //   cl("当前触发事件的元素是:", ev.target);
    // });
  </script>
</html>

QQ截图20200606235156.jpg
三、事件捕获与冒泡的原理
事件捕获: 就是像捕鱼收网那样,从外向里面触发。
冒泡: 像水烧开了一样,从内向外面扩散触发。
QQ截图20200606235954.jpg

四、总结:通过本节课的学习对捕获与冒泡的原理有了认识,知道了事件委托/代理的实现方式,DOM中的NodeList与HTMLCollectio区别。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议