Blogger Information
Blog 57
fans 3
comment 0
visits 60520
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JS基础-DOM操作/HTML节点类型/操作class属性值/元素自定义数据属性操作/元素添加事件处理
岂几岂几
Original
2155 people have browsed it

DOM 操作

1. DOM 对象

  • 节点: HTML 文件中所有内容都是节点
  • 节点树: 节点按照一定的结构组成的树形结构, 也叫 DOM 树
  • 节点类型: HTML 标签元素, 文本(标签中的文本), 属性(样式属性节点, style), 注释, 文档节点(就是当前 HTML)
  • 访问页面中的内容都要通过 document 对象(文档对象)的属性或者方法
  • 获取元素的返回值, 可以是 HTMLCollection, DOM 元素, NodeList等.
    • HTMLCollection: 类数组(类是”类似”的类), 但并不是数组, 元素键名是从 0 开始, 有一个 length 的属性, 表示其元素数量. 不能使用 forEach 遍历(用 for 遍历). 访问 HTMLCollection 对象的元素的方法:
      • HTMLCollection[index] : 类似数组访问元素的方式.
      • HTMLCollection.item(index) : 通过 HTMLCollection 对象的 item(index) 方法.
      • HTMLCollection.nameItem(元素name属性值) : 通过 HTML Collection 对象的 nameItem() 方法, 传入的参数是要获取的类数组中的元素的 name 属性值.
    • NodeList 类型数据, 取元素值, 同样跟数组类似, 有 length 属性, 有 forEach 和 item 方法.
      • 获取 NodeList 对象中的元素的方法跟数组类似, NodeList.childNodes[0] .
      • 另一种方法: NodeList.item(0) .
      • 可以用 for 或 forEach 遍历 NodeList 中的元素.
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>DOM对象</title>
  7. </head>
  8. <body>
  9. <form action="test1.php"></form>
  10. <form action="test2.php"></form>
  11. <form action="test3.php" id='loginForm' name="login">
  12. <input type="text" name="username" id="username" value="zhangsan">
  13. </form>
  14. </body>
  15. <script>
  16. // 给console.log()函数绑定一个别名
  17. var cl = console.log.bind(console);
  18. // 1. 查看当前文档类型, 即<!DOCTYPE html>
  19. cl(document.doctype);
  20. // 2. 查看根节点, 即<html>元素
  21. /* document并不代表根节点, document.documentElement才是 */
  22. cl(document.documentElement);
  23. // 3. 查看head部分, 即<head>元素
  24. cl(document.head);
  25. // 4. 查看body部分, 即<body>元素
  26. cl(document.body);
  27. /* ↑有了document.head和document.body, 就能使用上下级关系访问节点树中的子节点 */
  28. // 5. 查看<title>元素
  29. /* 方法1: 使用节点树获取 */
  30. cl(document.head.title);
  31. /* 方法2: 使用document对象的title属性获取 */
  32. cl(document.title);
  33. // 6. 获取当前HTML文档中的所有表单
  34. // 6.1 获取表单对象
  35. /* 返回值为: HTMLCollection对象, 类数组, 但并不是数组 */
  36. /* 遍历HTMLCollection对象中的元素, 见temp */
  37. cl(document.forms);
  38. // 6.2 获取表单中的元素/获取HTMLCollection对象中的元素
  39. /* 方法1: 采用类似数组的获取方式. ↓获取第2个表单 */
  40. cl(document.forms[1]);
  41. /* 方法2: 使用HTMLCollection提供的item(元素索引)方法. ↓获取第3个表单 */
  42. cl(document.forms.item(2));
  43. /* 方法3: 根据元素id获取表单(document.getElementById(id值)可以根据id获取所有元素) */
  44. cl(document.getElementById('loginForm'));
  45. /* 方法4: 使用HTMLCollection对象提供的nameItem(name属性值)来获取HTMLCollection中的元素 */
  46. cl(document.forms.namedItem('login'));
  47. // 6.3 获取某个表单中的表单控件的值
  48. /* input:text控件: 表单对象.控件的name属性值.value */
  49. cl(document.forms.item(2).username.value);
  50. </script>
  51. </html>

2. 获取 DOM 元素

  • 通过 document 对象, 利用 HTML 文档元素的树形结构, 可以使用”父级元素. 子级元素”的方式获取 DOM 元素; 也可以使用 document 中提供的一些方法获取到一些固定类型的 DOM 元素, 如: form 元素, title 元素等. 详见 DOM 对象的实例.

  • 还是通过 document 对象提供的方法, 利用元素的属性值来获取 DOM 元素.

    • 2.1 根据标签名来获取元素: document.getElementsByTagName(元素标签名) , 返回值: HTMLCollection 对象;
    • 2.2 根据 id 属性值来获取元素: document.getElementById(id值) , 返回值: DOM 元素(Element 对象).
    • 2.3 根据样式类来获取元素: document.getElementsByClassName(样式类名) , 返回值: HTMLCollection 对象;
    • 2.4 根据 name 属性值来获取元素: document.getElementsByName(name属性值) , 返回值: HTMLCollection 对象;
    • 2.5 根据 css 选择器来获取一个元素: document.querySelector(css选择器表达式) , 返回值: DOM 元素(Element 对象), 若匹配到多个元素, 则返回第一个.
    • 2.6 根据 css 选择器来获取多个元素: document.querySelector(css选择器表达式) , 返回值: 元素数组;
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>获取DOM元素</title>
  7. </head>
  8. <body>
  9. <ul class="list">
  10. <li class="item" name="first">item1</li>
  11. <li class="item" id="item2">item2</li>
  12. <li class="item active">item3</li>
  13. <li class="item">item4</li>
  14. <li class="item" id="item2">item5</li>
  15. </ul>
  16. </body>
  17. <script>
  18. var cl = console.log.bind(console);
  19. // 2.1 根据标签名来获取元素: `document.getElementsByTagName(元素标签名)`, 返回值: HTMLCollection 对象;
  20. /* 获取所有li标签元素 */
  21. var lis = document.getElementsByTagName("li");
  22. cl(lis);
  23. // 2.2 根据 id 属性值来获取元素: `document.getElementById(id值)`, 返回值: DOM 元素(Element 对象).
  24. /* 获取id属性值='item2'的元素, 匹配多个也只取1个 */
  25. var item2 = document.getElementById("item2");
  26. cl(item2);
  27. // 2.3 根据样式类来获取元素: `document.getElementsByClassName(样式类名)`, 返回值: HTMLCollection 对象;
  28. /* 获取设置有.list样式类的元素 */
  29. var ul = document.getElementsByClassName("list");
  30. cl(ul);
  31. /* 获取同时设置有.item和.active样式类的元素 */
  32. var activeItem = document.getElementsByClassName("item active");
  33. cl(activeItem);
  34. // 2.4 根据 name 属性值来获取元素: `document.getElementsByName(name属性值)`, 返回值: HTMLCollection 对象;
  35. /* 获取name属性值为fist的元素, 因返回值是类数组, 所以调用其item(0)方法获取到第一个元素 */
  36. var firstItem = document.getElementsByName("first").item(0);
  37. cl(firstItem);
  38. // 2.5 根据 css 选择器来获取一个元素: `document.querySelector(css选择器表达式)`, 返回值: DOM 元素(Element 对象), 若匹配到多个元素, 则返回第一个.
  39. /* 获取css选择器表达式是.item匹配到的第一个元素 */
  40. var item = document.querySelector(".item");
  41. cl(item);
  42. // 2.6 根据 css 选择器来获取多个元素: `document.querySelector(css选择器表达式)`, 返回值: **元素数组**;
  43. /* 获取css选择器表达式是.item匹配到的所有元素 */
  44. var items = document.querySelectorAll(".item");
  45. cl(items);
  46. /* 获取css选择器表达式是".item:nth-child(-n + 3)"(即前三个)匹配到的所有元素 */
  47. var items = document.querySelectorAll(".item:nth-child(-n + 3)");
  48. cl(items);
  49. /* 遍历这3个元素, 并赋给红色字体样式 */
  50. items.forEach(function (item, index, items) {
  51. item.style.color = "red";
  52. });
  53. </script>
  54. </html>

3. 获取子节点

  • 在 JS 中, 节点类型共有 11 种, 跟 HTML 相关的有 6 种(其他 5 种和 XML 相关), 元素节点只是其中之一.
  • 与 HTML 相关的 6 种元素类型:
    • 元素: 类型值(1);
    • 属性: 类型值(2);
    • 文本: 类型值(3);
    • 注释: 类型值(6);
    • 文档节点: 即 document 对象, 类型值(9);
    • 文档片段: 类型值(11).
  • 获取当前元素的所有类型的子节点: element.childNodes , 返回类型为 NodeList 类型数据, 取元素值, 跟数组类似, 有 length 属性, 有 forEach 和 item 方法.
    • 获取 NodeList 对象中的元素的方法跟数组类似, NodeList.childNodes[0] .
    • 另一种方法: NodeList.item(0) .
    • 用 for 或 forEach 遍历 NodeList 中的元素.
    • 获取节点类型的属性: element.nodeType .
    • 获取节点的名称: element.nodeName .
    • 获取节点的值: element.nodeValue . 只有文本节点才能获得值.
  • 获取当前元素的第一个子节点: element.firstChild .
  • 获取当前元素的最后一个子节点: element.lastChild .
  • 获取当前节点的前一个兄弟节点: element.previousSibling .
  • 获取当前节点的后一个兄弟节点: element.nextSibling .
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>节点类型</title>
  7. </head>
  8. <body>
  9. <ul>
  10. <li>item1</li>
  11. <li>item2</li>
  12. <li>item3</li>
  13. <li>item4</li>
  14. <li>item5</li>
  15. </ul>
  16. </body>
  17. <script>
  18. var cl = console.log.bind(console);
  19. // 获取第一个ul元素
  20. var ul = document.querySelector("ul");
  21. // 1. 获取ul元素的所有类型的子节点
  22. var nodes = ul.childNodes;
  23. /* 包括5个元素类型节点和6个文本类型节点(回车换行) */
  24. cl(nodes);
  25. // 2. 遍历ul元素的子节点, 打印其节点属性信息
  26. nodes.forEach(function (node, index, nodes) {
  27. cl(
  28. "第",
  29. index + 1,
  30. "个节点信息: 节点类型: ",
  31. node.nodeType,
  32. "; 节点名称: ",
  33. node.nodeName,
  34. "; 节点值: ",
  35. node.nodeValue
  36. );
  37. });
  38. // 3. 获取ul元素的第一个子节点
  39. cl(ul.firstChild);
  40. // 4. 获取ul元素的最后一个子节点
  41. cl(ul.lastChild);
  42. // 5. 获取ul元素的第5个子节点的上一个节点/下一个节点
  43. cl(ul.childNodes.item(6).previousSibling);
  44. cl(ul.childNodes.item(6).nextSibling);
  45. </script>
  46. </html>

4. 操作元素的 class 属性

4.1 使用 element.className 操作

  • element.className 以文本的形式返回元素的 class 属性的值.
  • 因为 class 属性名也是 js 的保留字, 所以用 className 来获取 class 属性的值.

4.2 使用 element.classList 操作

  • element.classList 提供了很多便捷的操作 class 属性值的方法
    • element.classList.add(样式类名) : 为元素添加样式类.
    • element.classList.remove(样式类名) : 为元素移除样式类.
    • element.classList.toggle(样式类名) : 为元素以开关的方式增加/移除样式类.
    • element.classList.replace(旧样式类名, 新样式类名) : 为元素把旧样式替换成新样式, 若没有旧样式, 则直接添加新样式.
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>className和classList操作class属性值</title>
  7. <style>
  8. .red {
  9. color: red;
  10. }
  11. .bgc {
  12. background-color: yellow;
  13. }
  14. .blue {
  15. color: blue;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <p class="red">hello JavaScript!</p>
  21. <h3>hello JS!</h3>
  22. <script>
  23. var cl = console.log.bind(console);
  24. var p = document.querySelector("p");
  25. // 获取<p>的class属性, 注意, class是js是保留字, 不能用, 所以用className代替
  26. cl(p.clasName);
  27. // 1. 使用className属性操作元素样式类
  28. // 样式类(增,删,替换等)
  29. p.className = "bgc";
  30. p.className = "red bgc";
  31. // 上面的方式很麻烦, 使用classList对象就容易操作了
  32. var h3 = document.querySelector("h3");
  33. // 2. 使用classList属性操作元素样式类
  34. // 为元素添加样式类
  35. h3.classList.add("red");
  36. h3.classList.add("bgc");
  37. // 移除元素的样式类
  38. h3.classList.remove("bgc");
  39. // 自动切换, 即当前如果有某个样式类, 则删除该样式类, 没有, 则添加该样式类
  40. h3.classList.toggle("red");
  41. // 替换样式类replace(旧样式类, 新样式类)
  42. h3.classList.replace("bgc", "red");
  43. </script>
  44. </body>
  45. </html>

5. 使用 dataset 对象处理用户自定义的数据属性

  • 用户可以在元素中定义自定义的数据属性, 格式是属性名以 data- 为前缀. 如: data-id , data-username 等.
  • 获取用户自定义数据属性的方式: element.dataset.去掉前缀的自定义属性名 .
    • 如果自定义的属性名是两个单词用短横线相连, 则转为小驼峰命名. 如: data-user-name , 获取时: element.dataset.userName .
  • 赋值: element.dataset.去掉前缀的自定义属性名 = 新值 .
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>dataset对象:用于处理用户自定义的数据属性</title>
  7. </head>
  8. <body>
  9. <!-- html5中, 可以使用自定义的数据属性保存标签的附加信息, 以"data-"为前缀 -->
  10. <div id="user" data-id="1" data-user-name="zhangsan" data-email="zs@qq.com">用户信息</div>
  11. <script>
  12. var cl = console.log.bind(console);
  13. // 获取元素
  14. var user = document.querySelector('div');
  15. // 1. 获取自定义属性值
  16. // dataset对象用于获取用户自定义的数据属性。使用方法:dataset(去掉"data-"前缀的数据属性名)
  17. cl(user.dataset.id);
  18. cl(user.dataset.email);
  19. // 多单词属性,把中间连接线删除,第二个单词字母大写,形成驼峰命名
  20. cl(user.dataset.userName);
  21. // 2. 设置自定义属性值
  22. // 同样也可以用dataset设置用户自定义数据属性的值
  23. user.dataset.email = 'zhangsan@qq.com';
  24. cl(user.dataset.email);
  25. </script>
  26. </body>
  27. </html>

6. 为元素添加事件处理脚本

6.1 使用元素的 onxxx 属性添加

js常用的事件: https://www.cnblogs.com/theblogs/p/9972319.html

以添加点击事件为例:

  • 添加 onclick 属性: <button onclick="...">提交</button>
  • onclick 属性的值可以是调用 js 函数的表达式, 也可以是其他 js 表达式.
  • 也可以在 js 脚本中添加: button.onclick = function(event) {...} .

6.2 使用监听器的方式添加

  • 为元素添加事件监听的方法是: element.addEventListener(事件类型, 回调函数, 事件传递机制) . 事件传递机制见第7点.
  • 监听器可以认为是一个内部方法, 几乎所有元素都有.
  • 事件传递机制有捕获(参数值为 true)和冒泡(参数值为 false).

6.3 事件派发(使用代码触发事件)

  • 一般的事件都由用户主动触发, 如用户点击, 用户移动鼠标进入区域等. 可以用事件派发的方式, 由代码来触发事件.
  • 事件派发的使用场景之一: 轮播图.
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>事件添加方式</title>
  7. </head>
  8. <body>
  9. <!-- 方式1: onclick属性指定处理的js函数或表达式 -->
  10. <!-- 1.1: 直接写js代码 -->
  11. <button onclick="var text=this.innerText;alert(text);">按钮1</button>
  12. <!-- 1.2: 调用js函数 -->
  13. <button onclick="show(this)">按钮2</button>
  14. <!-- 方式2: 给html元素添加属性 -->
  15. <button>按钮3</button>
  16. <!-- 方式3: 监听器方式 -->
  17. <button>按钮4</button>
  18. <!-- 方式4: 事件派发 -->
  19. <button>按钮5</button>
  20. </body>
  21. <script>
  22. // 给console.log起别名
  23. var cl = console.log.bind(console);
  24. /* 方式1.2 */
  25. function show(element) {
  26. var text = element.innerText;
  27. alert(text);
  28. }
  29. /* 方式2: 给html元素添加onclick属性 */
  30. var btn3 = document.querySelector('button:nth-of-type(3)');
  31. btn3.onclick = function() {
  32. alert(this.nodeName);
  33. }
  34. /* 方式3: 监听器方式 */
  35. // 监听器可以认为是一个内部方法, 几乎所有元素都有. element.addEventListener(事件类型, 事件回调函数, 传递机制);
  36. // 其中传递机制有两种, 一种是捕获(值为true), 一种是冒泡(值为false), 即: 冒泡阶段触发. 见demo7.html
  37. var btn4 = document.querySelector('button:nth-of-type(4)');
  38. btn4.addEventListener('click', function(){
  39. alert(this.innerText);
  40. }, false);
  41. /* 方式4: 事件派发(可以模拟自动触发, 而不需要用户点击触发) */
  42. // 先给按钮5添加一个点击事件
  43. var btn5 = document.querySelector('button:nth-of-type(5)');
  44. btn5.addEventListener('click', function(){
  45. console.log(this.innerText);
  46. }, false);
  47. // 创建一个点击事件对象
  48. var event = new Event('click');
  49. // 派发给btn5(执行派发语句后, 立刻触发btn5的点击事件,不用用户点击)
  50. btn5.dispatchEvent(event);
  51. // 事件派发使用场景: 轮播图
  52. </script>
  53. </html>

7. 事件传递机制

  • 事件传递机制有两种: 捕获冒泡.

    • 捕获是由长辈元素向后辈元素传递事件触发. 从最大的长辈元素(即, 根元素 <html> )开始, 一直传递到事件触发的最小后辈元素为止. 事件触发传递到的元素上绑定有事件对应的处理脚本的, 则执行事件处理脚本.
    • 冒泡是有最小触发事件的元素向长辈元素方向传递事件触发. 一直传递到最大的长辈元素(即, 根元素 <html> )为止. 事件触发传递到的元素上绑定有事件对应的处理脚本的, 则执行事件处理脚本.

事件传递之捕获:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>事件传递之捕获</title>
  7. <style>
  8. .first {
  9. padding: 30px;
  10. background-color: yellow;
  11. }
  12. .second {
  13. padding: 30px;
  14. background-color: red;
  15. }
  16. .third {
  17. width: 100px;
  18. height: 100px;
  19. background-color: lightgreen;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div class="first">
  25. <div class="second">
  26. <div class="third">事件传递</div>
  27. </div>
  28. </div>
  29. </body>
  30. <script>
  31. var cl = console.log.bind(console);
  32. // 事件捕获与冒泡(两种处理父子元素之间事件传递的方式)
  33. // 当最内层元素节点被点击时, 认为是从最外层元素节点, 向最内层元素节点传递事件, 最后由最内层元素节点触发事件. 这个由外向内传递事件的过程叫捕获
  34. // 当最内层元素节点被点击时, 认为是从最内层元素节点, 向最外层元素节点传递事件, 最后由最外层元素节点触发事件. 这个由内向外传递事件的过程叫冒泡
  35. var first = document.querySelector('.first');
  36. var second = document.querySelector('.second');
  37. var third = document.querySelector('.third');
  38. // 根元素添加点击事件
  39. document.documentElement.addEventListener('click', function (ev) {
  40. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.nodeName);
  41. }, true);
  42. // body元素添加点击事件
  43. document.body.addEventListener('click', function (ev) {
  44. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.nodeName);
  45. }, true);
  46. // addEventListener()第三个入参值为true,表示捕获阶段触发事件.
  47. first.addEventListener('click', function (ev) {
  48. // ev:事件对象(Event),可以通过它了解很多事件信息
  49. // 事件类型(是点击,还是双击,等等)
  50. cl(ev.type);
  51. // 触发事件的元素
  52. cl(ev.target);
  53. // 绑定事件的元素
  54. cl(ev.currentTarget);
  55. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.className);
  56. }, true);
  57. second.addEventListener('click', function (ev) {
  58. // ev:事件对象(Event),可以通过它了解很多事件信息
  59. // 事件类型(是点击,还是双击,等等)
  60. cl(ev.type);
  61. // 触发事件的元素
  62. cl(ev.target);
  63. // 绑定事件的元素
  64. cl(ev.currentTarget);
  65. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.className);
  66. }, true);
  67. third.addEventListener('click', function (ev) {
  68. // ev:事件对象(Event),可以通过它了解很多事件信息
  69. // 事件类型(是点击,还是双击,等等)
  70. cl(ev.type);
  71. // 触发事件的元素
  72. cl(ev.target);
  73. // 绑定事件的元素
  74. cl(ev.currentTarget);
  75. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.className);
  76. }, true);
  77. </script>
  78. </html>

事件传递之冒泡:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>事件传递之冒泡</title>
  7. <style>
  8. .first {
  9. padding: 30px;
  10. background-color: yellow;
  11. }
  12. .second {
  13. padding: 30px;
  14. background-color: red;
  15. }
  16. .third {
  17. width: 100px;
  18. height: 100px;
  19. background-color: lightgreen;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div class="first">
  25. <div class="second">
  26. <div class="third">事件传递</div>
  27. </div>
  28. </div>
  29. </body>
  30. <script>
  31. var cl = console.log.bind(console);
  32. // 事件捕获与冒泡(两种处理父子元素之间事件传递的方式)
  33. // 当最内层元素节点被点击时, 认为是从最外层元素节点, 向最内层元素节点传递事件, 最后由最内层元素节点触发事件. 这个由外向内传递事件的过程叫捕获
  34. // 当最内层元素节点被点击时, 认为是从最内层元素节点, 向最外层元素节点传递事件, 最后由最外层元素节点触发事件. 这个由内向外传递事件的过程叫冒泡
  35. var first = document.querySelector('.first');
  36. var second = document.querySelector('.second');
  37. var third = document.querySelector('.third');
  38. // 根元素添加点击事件
  39. document.documentElement.addEventListener('click', function (ev) {
  40. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.nodeName);
  41. }, false);
  42. // body元素添加点击事件
  43. document.body.addEventListener('click', function (ev) {
  44. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.nodeName);
  45. }, false);
  46. // addEventListener()第三个入参值为false,表示冒泡阶段触发事件. 目前冒泡是更流行的事件传递方式
  47. first.addEventListener('click', function(ev){
  48. // ev:事件对象(Event),可以通过它了解很多事件信息
  49. // 事件类型(是点击,还是双击,等等)
  50. cl(ev.type);
  51. // 触发事件的元素
  52. cl(ev.target);
  53. // 绑定事件的元素
  54. cl(ev.currentTarget);
  55. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.className);
  56. }, false);
  57. second.addEventListener('click', function(ev){
  58. // ev:事件对象(Event),可以通过它了解很多事件信息
  59. // 事件类型(是点击,还是双击,等等)
  60. cl(ev.type);
  61. // 触发事件的元素
  62. cl(ev.target);
  63. // 绑定事件的元素
  64. cl(ev.currentTarget);
  65. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.className);
  66. }, false);
  67. third.addEventListener('click', function(ev){
  68. // ev:事件对象(Event),可以通过它了解很多事件信息
  69. // 事件类型(是点击,还是双击,等等)
  70. cl(ev.type);
  71. // 触发事件的元素
  72. cl(ev.target);
  73. // 绑定事件的元素
  74. cl(ev.currentTarget);
  75. cl('捕获阶段:' + '触发元素:' + ev.target.className + ';', '事件绑定的元素:' + ev.currentTarget.className);
  76. }, false);
  77. </script>
  78. </html>

8. 利用事件冒泡实现事件委托/代理

  • 应用场景和实现原理: 当需要为多个元素添加相同的事件处理脚本时, 可以把事件处理脚本绑定到这些元素共同的长辈元素上, 通过事件冒泡, 委托长辈元素执行事件处理脚本.
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>冒泡实现事件委托案例</title>
  7. <style>
  8. .item {
  9. height: 32px;
  10. margin: 10px;
  11. background-color: #f1f1f1;
  12. }
  13. </style>
  14. </head>
  15. <body>
  16. <span>当某个元素中的多个子元素都拥有某个相同的事件时, 如果要为每个子元素添加事件, 会很麻烦, 使用事件委托, 即, 把事件绑定到父元素上, 通过冒泡的方式, 把事件传递到父元素上的同名事件上触发</span>
  17. <ul>
  18. <li class="item">item1</li>
  19. <li class="item">item2</li>
  20. <li class="item">item3</li>
  21. <li class="item">item4</li>
  22. <li class="item">item5</li>
  23. </ul>
  24. <script>
  25. // 给console.log方法取别名
  26. var cl = console.log.bind(console);
  27. // 获取父元素
  28. var ul = document.querySelector('ul')
  29. // 事件绑定在父元素上
  30. ul.addEventListener('click', function(e) {
  31. // 在事件回调函数中, this===e.target, 即触发事件的元素.
  32. cl(e.target.innerText + '被点击了, 但是它没有绑定点击处理函数, 所以它执行的是绑定在' + e.currentTarget.nodeName + '上的事件处理方法');
  33. }, false);
  34. </script>
  35. </body>
  36. </html>

学习心得

  • NodeList和HTMLCollection的区别: 前者有forEach方法, 后者没有. 其他的, 如像数组一样访问元素的方式, item(index) 方法, length 属性, 元素键名从0开始, nameItem(name属性值) 方法 等, 二者都有.

  • 在 JS 中, 节点类型共有 11 种, 跟 HTML 相关的有 6 种(其他 5 种和 XML 相关), 元素节点只是其中之一.

  • 事件的添加方式有: 1. 为元素添加”on事件名”属性; 2. 在js脚本中, 以”元素.on事件名=匿名函数”的方式添加; 3. 使用监听器( addEventListener(事件名, 回调函数, 传递机制) )的方式添加.

  • 当需要为多个元素添加相同的事件处理脚本时, 可以把事件处理脚本绑定到这些元素共同的长辈元素上, 通过事件冒泡, 委托长辈元素执行事件处理脚本.

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:图片做得不错, 事件机制是个难点, 其实理解了也非常简单是不是?
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