事件(下)

168 阅读4分钟

事件·下

阻止事件冒泡和默认行为

事件流

 事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候, 
 那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,
 而层叠在你点击范围的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获。

事件冒泡

 事件冒泡是从里往外逐个触发. 事件捕获, 是从外往里逐个触发. 
 现代的浏览器默认情况下都是事件冒泡的模式.
冒泡传递事件
document.onclick=function(){ 
      console.log('我是 document'); 
}; 
document.documentElement.onclick=function() { 
      console.log('我是 html'); 
}; 
document.body.onclick= function(){ 
      console.log('我是 body'); 
};
document.getElementById('box').onclick=function() { 
      console.log('我是 div'); 
}; 
document.getElementsByTagName('input')[0].onclick= function(){
      console.log('我是 input'); 
};
输出依次为我是 input 我是 div 我是 body 我是 html 我是 document

但是一般我们只在指定的节点上添加事件, 而不想让其传递到下层节点触发事件, 
这样我们就需要阻止事件冒泡;
阻止事件冒泡有两个方法: 
( 在指定不想再继续传递事件的节点的事件执行函数中使用)
1, 取消冒泡,  IE
     e.cancelBubble = true; 
2, 停止传播, 非IE
     e.stopPropagation(); 

例如: 
document.getElementsByTagName('input')[0].onclick= function(evt){
  var e = evt || window.event;
可以通过下述方法取消事件冒泡 兼容写法
  if(e.stopPropagation){
     e.stopPropagation();
  }else{
     e.cancelBubble = true 
  };
  ------------------
  e.stopPropagation();
  
阻止浏览器默认行为 兼容写法
if (e.preventDefault) {
e.preventDefault();   //非IE
}
else {
e.returnValue = false;  // IE
}
------------------
return false; //重点1
------------------
e.preventDefault(); //重点2
<a>标签有属性href, 在用户点击超链接标签<a>时, 实际上内部会调用onclick事件,
那么如果我们需要在超链接跳转前做一些判断处理, 
则可以将onclick指向我们自己的函数,并返回true或者false来决定是否允许超链接跳转;

例如: 
var oA = document.getElementsByTagName("a")[0];
oA.onclick = function() {
      if(confirm("你确定要跳转吗?")) {
         return true;
      } else {
         return false;
      }
}
<a href=“http://www.baidu.com”>百度一下</a>


  
阻止右键菜单
在之前使用event对象的button属性时, 点击鼠标右键会弹出系统菜单, 
如果我们想要创建自己的右键菜单, 则需要先阻止默认的右键菜单
document.oncontextmenu = function(){
  console.log("右键被按下");
  return false;
}

拖拽

所谓拖拽: 就是按住元素后移动位置, 最后松开的过程

1, 实现拖拽相关的三大事件:

onmousedown : 鼠标按下
onmousemove : 鼠标移动
onmouseup : 鼠标松开

2, 实现拖拽思路:

1, 给目标元素添加onmousedown事件(鼠标按下事件)
    在鼠标按下的瞬间, 记录鼠标所在位置与目标元素左边界的距离disX, 
    以及与上边界的距离disY

2, 当onmousedown事件发生以后(鼠标按下后),就给document添加onmousemove事件(鼠标移动事件)
   在onmousemove(鼠标移动事件)中, 根据以下公式不断刷新目标元素所在的位置:
   公式: 目标元素的left = oEvent.clientX – disX + “px”;
         目标元素的top = oEvent.clientY – disY + “px”;

3, 在onmousedown事件(鼠标按下事件)发生以后,给document再添加onmouseup事件(鼠标松开事件),
   且在onmouseup事件中,取消document的onmousemove事件;
注意: 
onmousedown触发事件的对象: 目标元素(即要拖拽的元素); 
onmousemove触发事件的对象: document
onmouseup触发事件的对象: document

onmousemove和onmouseup的触发事件对象都是document,
意味着鼠标在网页的任意位置移动鼠标或松开鼠标,都会触发对应的事件;

onmousemove和onmouseup都要写在onmousedown事件中,
这样就可以保证鼠标按下后才可以移动目标元素(onmousemove)或停止移动(onmouseup)
onload = function() {
    var box = document.getElementById("box");
    //鼠标按下
    box.onmousedown = function(evt) {
        var e = evt || event;
        //计算鼠标位置与div左边和上边的距离
        var disX = e.clientX - box.offsetLeft;
        var disY = e.clientY - box.offsetTop;
        //鼠标移动
        document.onmousemove = function(evt) {
            var e = evt || event;
            box.style.left = e.clientX - disX + "px";
            box.style.top = e.clientY - disY + "px";
        }
        //鼠标松开
        document.onmouseup = function() {
            document.onmousemove = null;
            document.onmouseup = null;
        }
    }
}

事件监听器

事件监听器:
  事件监听器, 是JS事件中的一种事件触发机制, 
  我们可以通过添加事件监听器的方式给元素添加事件及执行函数

1 添加事件监听器

box.addEventListener(“click”, func, false) : 给box元素添加点击事件(click,不用加on), 
以及事件执行函数func. 针对该函数的三个参数作说明:
  第一个参数(“click”) : 事件名称(前面没有on)
  第二个参数(func): 事件执行函数名称(没有双引号,也没有())
  第三个参数(false/true) : 是否使用捕捉(反向冒泡),默认false,为冒泡

2 移除事件监听器

box.removeEventListener(“click”, func) : 将box元素的点击事件(click), 
以及对应的事件执行函数func移除
注: 这里只会删除使用box.addEventListener()方法添加的事件监听器
如果添加的函数不是唯一的,那么remove删除的就是一个新的函数,无法删除之前绑定的函数
原因是每次添加与删除的函数的地址是不一样的
例如:
oBox.addEventListener("click", function(){
    conlose.log("a")
})
其中function不唯一,每次添加的函数都是一个新的地址,所以删除时无法成功
解决方法:
将第二个参数的函数设为全局函数,使之地址唯一,就能删除

addEvent(aBtn[0], "click", fn, false);
//全局函数
function fn(){
  alert("click 按钮1");
}
aBtn[1].onclick = function(){
  removeEvent(aBtn[0], "click", fn, false);
}