十二、JavaScript事件
一、事件的传播和阻止
-
-
执行顺序:从当前标签向父级元素执行,也就是执行当前标签的事件,再逐一执行父级标签的事件
-
捕获顺序:当前标签触发事件,会寻找父级标签上相同的事件类型一起执行
-
冒泡机制:IE浏览器,从子级开始,向父级获取具有相同的事件类型
-
-
1 e.stopPropagation();
- 低版本IE浏览器:
1 e.cancelBubble = true;
- 谁写谁阻止,谁不触发父级,谁不写谁触发父级
1 // 大部分事件传播都是需要阻止的,只有特殊情况下才会允许事件的传播 2 // 使用if判断做兼容处理 3 if(e.stopPropagation){ 4 e.stopPropagation(); 5 }else{ 6 e.cancelBubble = true; 7 }
二、事件委托
-
-
通过父级标签触发事件,然后通过判断触发事件的对象,来判断需要执行的不同代码
-
绑定给父级标签对象的事件,触发时有可能是不同的标签对象,触发的事件
-
1 var oDiv = document.querySelector('div'); 2 3 // 给父级标签对象绑定事件 4 oDiv.addEventListener('click' , function(e){ 5 // 1,兼容事件对象e 6 e = e || window.event; 7 8 // 2,e.target中 存储点击对象的信息 9 console.dir(e.target); 10 11 if(e.target.id === 'span1' ){ 12 console.log('我是点击span1触发的'); 13 }else if (e.target.id === 'span2'){ 14 console.log('我是点击span2触发的'); 15 } 16 })
三、Tab切换
1、Tab切换之循环遍历
1 <div class="cont"> 2 <ul> 3 <li class="active">1</li> 4 <li>2</li> 5 <li>3</li> 6 </ul> 7 <ol> 8 <li class="active">内容1</li> 9 <li>内容2</li> 10 <li>内容3</li> 11 </ol> 12 </div> 13 14 <script> 15 var oUlLis = document.querySelectorAll('ul>li'); 16 var oOlLis = document.querySelectorAll('ol>li'); 17 18 // 给 ul>li标签 添加点击事件 19 oUlLis.forEach(function(item, key){ 20 item.addEventListener('click', function(){ 21 // ul>li和ol>li都清除active样式 22 oUlLis.forEach(function(i, k){ 23 i.className = ''; 24 oOlLis[k].className = ''; 25 }) 26 // 给点击的标签添加样式 27 item.className = 'active'; 28 oOlLis[key].className = 'active'; 29 }) 30 }) 31 </script>
2、Tab切换之事件委托
-
-
缺点:
-
没有通过循环遍历,给所有ul>li添加事件,没有获取到索引下标
-
-
1 <div class="cont"> 2 <ul> 3 <li index="0" name="ulli" class="active">1</li> 4 <li index="1" name="ulli">2</li> 5 <li index="2" name="ulli">3</li> 6 </ul> 7 <ol> 8 <li class="active">内容1</li> 9 <li>内容2</li> 10 <li>内容3</li> 11 </ol> 12 </div> 13 14 <script> 15 var oDiv = document.querySelector('.cont'); 16 var oUlLis = document.querySelectorAll('ul>li'); 17 var oOlLis = document.querySelectorAll('ol>li'); 18 19 oDiv.addEventListener('click', function(e){ 20 // 兼容事件对象 21 e = e || window.event; 22 23 // 通过name属性的不同属性值来区分li 24 if(e.target.getAttribute('name') === 'ulli'){ 25 // 清除样式 26 oUlLis.forEach(function (item, key) { 27 a = key; 28 item.className = ''; 29 oOlLis[key].className = ''; 30 }) 31 32 // 给当前点击的ul>li标签,设定class样式 33 e.target.className = 'active'; 34 // ol>li与ul>li下标通用,设定class样式 35 oOlLis[e.target.getAttribute('index')].className = 'active'; 36 } 37 }) 38 </script>
四、事件对象的属性
-
-
e.target.parentElement:直接父级标签对象
-
e.target.parentNode:直接父级标签对象
-
e.target.tagName:触发事件的标签对象名称,全大写英文字母
-
点击事件中,e事件对象中存储坐标信息,只能获取鼠标点击的位置坐标,不能设定
-
键盘事件中,e事件对象中存储的按键信息
-
offsetX,offsetY
-
触发事件的标签对象,左上角为坐标原点
-
在鼠标拖拽时,鼠标坐标原点会改变
-
在整个页面中拖拽div
-
起始时坐标原点是 document 文档的左上角
-
当鼠标经过div时,坐标原点是 div 的左上角
-
获取的坐标数值不同,会造成 div 闪来闪去
-
-
-
clientX,clientY
-
视窗窗口,左上角为坐标原点
-
-
pageX,pageY
-
1、div点击移动
1 var oDiv = document.querySelector('div'); 2 // 给 document 整个文档添加点击事件 3 document.addEventListener('click' , function(e){ 4 e = e || window.event; 5 6 // 通过标签占位,获取标签的宽度高度占位 7 // offsetHeight offsetWidth 8 // 直接获取数据数值,没有px单位的 9 var h = oDiv.offsetHeight; 10 var w = oDiv.offsetWidth; 11 console.log(h,w); 12 13 // 因为有页面滚动的问题,使用:clientX和clientY 14 // div中心与鼠标位置重合,需要再减去div宽度高度的一半 15 var top = e.clientY - h/2; 16 var left = e.clientX - w/2; 17 18 // 设定为 div 的定位数据,并且拼接px单位 19 oDiv.style.top = top + 'px'; 20 oDiv.style.left = left + 'px'; 21 })
2、div拖拽移动
1 var oDiv = document.querySelector('div'); 2 // 给div添加鼠标按下事件 3 oDiv.addEventListener('mousedown', function () { 4 document.addEventListener('mousemove', myMove); 5 }) 6 7 // 鼠标抬起移除鼠标移动事件 8 oDiv.addEventListener('mouseup', function () { 9 document.removeEventListener('mousemove', myMove); 10 }) 11 12 function myMove(e) { 13 e = e || window.event; 14 15 // 获取鼠标坐标位置 16 // 使用offsetY,offsetX会造成div闪来闪去 17 // 鼠标拖拽,不能使用offsetY,offsetX 18 // 在鼠标拖拽时,要使用clientX和clientY获取坐标 19 var top = e.clientY; 20 var left = e.clientX; 21 22 // 获取div标签的相关数据 23 var h = oDiv.offsetHeight; 24 var w = oDiv.offsetWidth; 25 26 // 如果需要div中心位置和鼠标位置重合 27 // 需要减去占位的一半 28 oDiv.style.top = top - h / 2 + 'px'; 29 oDiv.style.left = left - w / 2 + 'px'; 30 }