事件流:描述从页面中接收事件的顺序 冒泡 捕获

事件捕获阶段、处于目标阶段、事件冒泡阶段

IE 提出的 事件冒泡流 (Event Bubbling)

Netscape 提出的 事件捕获流 (Event Capturing)

DOM0 onXXX onmouseover onmouseout

DOM1 没有 定义事件模型

DOM2 addEventListener(3个参数) -> W3C规范

removeEventListener

onclick
冒泡 事件源向父级,当父级绑定相同事件时触发父级绑定的事件,其实点击事件所以元素都有,只不过元素默认没有触发事件,为空
捕获 事件源相同的事件,事件源的事件先不触发,找父级是否有相同的事件,找到绑定相同事件的最外层元素,绑定事件与尽量外层同时满足,从那个父元素指向事件源的方向,那个父元素的点击事件触发,再向子元素传递事件,传递到事件源

image.png
事件流:
事件捕获:
事件冒泡:
处于捕获:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title></title>
  8. </head>
  9. <div></div>
  10. <button></button>
  11. <body>
  12. <script>
  13. var div =document.getElementsByTagName('div')[0];
  14. console.log(div.onclick)
  15. div.onclick = function() {
  16. console.log('div')
  17. }
  18. // div.addEventListener('click',function() {
  19. // console.log('div')
  20. // },false)
  21. console.log(div.onclick)
  22. </script>
  23. </body>
  24. </html>

image.png

事件源对象 target srcElement

fixfox : target
IE : srcElement
chrome target srcElement

demo 输出点击li的内容 含包括新增项目

  1. <body>
  2. <button>增加</button>
  3. <ul>
  4. <li>1</li>
  5. <li>2</li>
  6. <li>3</li>
  7. <li>4</li>
  8. <li>5</li>
  9. <li>6</li>
  10. <li>7</li>
  11. <li>8</li>
  12. <li>9</li>
  13. <li>10</li>
  14. </ul>
  15. </body>
  16. <script>
  17. var oList = document.getElementsByTagName('ul')[0],
  18. oLi = document.getElementsByTagName('li'),
  19. oBtn = document.getElementsByTagName('button')[0],
  20. len = oLi.length,
  21. item;
  22. for(var i = 0;i<len;i++){
  23. item = oLi[i];
  24. item.onclick = function(){
  25. console.log(this.innerText);
  26. }
  27. }
  28. oBtn.onclick = function(){
  29. var li = document.createElement('li');
  30. li.innerText = oLi.length + 1;
  31. oList.appendChild(li);
  32. }
  33. </script>

结果 无法输出新增项目 因为第一次就循环绑定了所有的li 但并不包括后面新增的

事件委托 事件代理

  1. <body>
  2. <button>增加</button>
  3. <ul>
  4. <li>1</li>
  5. <li>2</li>
  6. <li>3</li>
  7. <li>4</li>
  8. <li>5</li>
  9. <li>6</li>
  10. <li>7</li>
  11. <li>8</li>
  12. <li>9</li>
  13. <li>10</li>
  14. </ul>
  15. </body>
  16. <script>
  17. var oList = document.getElementsByTagName('ul')[0],
  18. oLi = document.getElementsByTagName('li'),
  19. oBtn = document.getElementsByTagName('button')[0],
  20. len = oLi.length,
  21. item;
  22. // 事件委托 事件代理
  23. oList.onclick = function(e){ //事件对象 事件对象有属性,可以找到哪个元素触发了事件
  24. console.log(e);
  25. var e = e || window.event,
  26. tar = e.target || e.srcElement;
  27. console.log(tar.innerText);
  28. }
  29. oBtn.onclick = function(){
  30. var li = document.createElement('li');
  31. li.innerText = oLi.length + 1;
  32. oList.appendChild(li);
  33. }
  34. </script>

如果没有事件委托,必须循环,循环就会消耗性能

打印下标 闭包写法 (缺点无法打印新增项下标)

  1. <body>
  2. <button>增加</button>
  3. <ul>
  4. <li>1</li>
  5. <li>2</li>
  6. <li>3</li>
  7. <li>4</li>
  8. <li>5</li>
  9. <li>6</li>
  10. <li>7</li>
  11. <li>8</li>
  12. <li>9</li>
  13. <li>10</li>
  14. </ul>
  15. </body>
  16. <script>
  17. var oList = document.getElementsByTagName('ul')[0],
  18. oLi = document.getElementsByTagName('li'),
  19. oBtn = document.getElementsByTagName('button')[0],
  20. len = oLi.length,
  21. item;
  22. // 事件委托 事件代理
  23. oList.onclick = function (e) {
  24. console.log(e);
  25. var e = e || window.event,
  26. tar = e.target || e.srcElement;
  27. // console.log(tar.innerText);
  28. for (var i = 0; i < len; i++) {
  29. item = oLi[i];
  30. if(tar === item){
  31. console.log(i);
  32. }
  33. }
  34. }
  35. oBtn.onclick = function(){
  36. var li = document.createElement('li');
  37. li.innerText = oLi.length + 1;
  38. oList.appendChild(li);
  39. }
  40. </script>

image.png
image.png
得到下标,得到数字

Array.prototype.indexOf.call 写法

  1. <body>
  2. <button>增加</button>
  3. <ul>
  4. <li>1</li>
  5. <li>2</li>
  6. <li>3</li>
  7. <li>4</li>
  8. <li>5</li>
  9. <li>6</li>
  10. <li>7</li>
  11. <li>8</li>
  12. <li>9</li>
  13. <li>10</li>
  14. </ul>
  15. </body>
  16. <script>
  17. var oList = document.getElementsByTagName('ul')[0],
  18. oLi = document.getElementsByTagName('li'),
  19. oBtn = document.getElementsByTagName('button')[0],
  20. len = oLi.length,
  21. item;
  22. // 事件委托 事件代理
  23. oList.onclick = function (e) {
  24. console.log(e);
  25. var e = e || window.event,
  26. tar = e.target || e.srcElement;
  27. // console.log(tar.innerText);
  28. var index = Array.prototype.indexOf.call(oLi,tar);
  29. console.log(index);
  30. }
  31. oBtn.onclick = function(){
  32. var li = document.createElement('li');
  33. li.innerText = oLi.length + 1;
  34. oList.appendChild(li);
  35. }
  36. </script>

课后作业 todolist 未做 10课已做