Blogger Information
Blog 31
fans 0
comment 0
visits 30248
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
DOM操作:分析NodeList与HTMLCollectio区别、事件
emy
Original
1014 people have browsed it

一、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区别。

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:nodelist, 还有不少子集,如radiionodelist, 以后会遇到的
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post