• 事件


    推文:

    JS阻止冒泡和取消默认事件(默认行为)

    深入浅出js事件

    js事件大全

    事件

    事件是可以被 JavaScript 侦测到的用户行为(可以这么理解,事件就是用户行为)。事件通常与函数配合使用(叫做“注册事件监听函数”),当监听到用户有这个行为,执行事件对应的函数,响应用户的行为。

    事件举例:

    • 鼠标点击
    • 页面或图像载入
    • 鼠标悬浮于页面的某个热点之上
    • 在表单中选取输入框
    • 确认表单
    • 键盘按键

    应用怎么通过事件与用户行为交互的

    过程为:针对要监听的行为注册事件——用户的某种行为触发事件——执行监听函数——响应用户行为(在设计模式中,这也叫做观察者模式)。

    比如给页面上一个按钮注册点击事件,事件的处理程序是改变页面背景色,当用户点击的时候(用户行为),就会触发按钮的点击事件,执行处理程序,从而改变页面的背景色。


    事件流概念

    事件流分为冒泡流和捕获流。

    当你点击页面的按钮时,可以认为你点击了这个按钮的同时,也点击了这个按钮的容器(父级元素),也可以认为你点击了页面。

    如果在它们身上都注册了点击事件,那么到底是哪个先接收到了事件呢?这就有了事件流的概念,描述的是页面中元素(dom对象)接收事件的顺序。

    由于历史原因,不同的浏览器开发团队提出了不同的事件流概念,也就是后来的事件冒泡和事件捕获,这两个描述的事件流顺序刚好是相反的。

    IE认为事件是冒泡的,从点击的元素开始逐级向上级传递,现在所有的浏览器都默认事件冒泡。

    而Netscape Communicator 团队则认为事件是从最外层传递进来的,叫做事件捕获,事件捕获的用意在于在事件到达预定目标之前捕获它。由于老版本的浏览器不支持,因此很少有人使用事件捕获。一般事件冒泡可以放心地使用,在有特殊需要时再使用事件捕获。

    “ DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段)。但是不同浏览器和版本之间这些划分时机并不一致

    假如我们点击一个div, 实际上是先点击document,然后点击事件传递到div,而且并不会在这个div就停下,div有子元素就还会向下传递,最后又会冒泡传递回document。

    为了兼容更多的浏览器,非特殊情况一般我们都是把事件添加到在事件冒泡阶段。

     哪些事件冒泡,哪些事件不冒泡

    根据事件类型的场景来分类:

    焦点事件

    blur,focus:不冒泡,所有浏览器都支持它。

    focusin,focusoutt:与 HTML 事件 focus , blur等价,但冒泡。

    focus 和 blur最大问题是它们不冒泡。所以在代理场景中下会用另外的focusin和focusoutt。比如在下拉列表等许多常用的效果中,事件代理往往非常的重要,因为许多在各个链接上触发的事件,往往可以很容易的在根节点中进行监听。这个转载了一篇关于focus和blur代理的译文——谈 focus 和 blur 的事件代理。

    鼠标事件

    除了 mouseenter 和 mouseleave,所有鼠标事件都会冒泡,也可以被取消,而取消鼠标事件将会影响浏览器的默认行为。

    click,dblclick(双击主鼠标按钮),mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup

    移动到后代元素上不会触发的:mouseenter,mouseleave

    得到另外一个元素时才触发,不仅仅是针对当前元素而言:mouseout,mouseover(在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发。)

    页面上的所有元素都支持鼠标事件。

    注意:取消鼠标事件的默认行为还会影响其他事件,因为鼠标事件与其他事件是密不可分的关系。比如:

    只有在同一个元素上相继触发 mousedown 和 mouseup 事件,才会触发 click 事件;如果mousedown 或 mouseup 中的一个被取消,就不会触发 click 事件。

    类似地,只有触发两次 click 事件,才会触发一次 dblclick 事件。如果有代码阻止了连续两次触发 click 事件(可能是直接取消 click事件,也可能通过取消 mousedown 或 mouseup 间接实现),那么就不会触发 dblclick 事件了。

    阻止冒泡

     w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true

    事件的注册

    分为在html中注册或者在js中注册,在js中注册也分为两种写法:dom0与dom2级的事件注册

    html中注册

    缺点是 HTML 与 JavaScript 代码紧密耦合,改动html中代码的同时也得改动js中的代码

    <input type="button" value="Echo Username" onclick="alert(username.value)">

    js中注册

    dom0级事件注册:

    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
    alert("Clicked");
    };

    删除事件:

    btn.onclick = null; //删除事件处理程序

    dom2级事件注册(addEventListener):三个参数,处理程序里的this都指向元素本身。

    var btn = document.getElementById("myBtn");
    btn.addEventListener("click", function(){
    alert(this.id);
    }, false);

    最后这个布尔值参数如果是 true,表示在捕获阶段调用事件处理程序;如果是 false,表示在冒泡阶段调用事件处理程序。上面这个程序会在事件冒泡阶段被触发

    使用 DOM2 级方法添加事件处理程序的主要好处是可以添加多个事件处理程序,事件按照注册顺序触发

    var btn = document.getElementById("myBtn");
    btn.addEventListener("click", function(){
    alert(this.id);
    }, false);
    btn.addEventListener("click", function(){
    alert("Hello world!");
    }, false);

    通过 addEventListener()添加的事件处理程序只能使用 removeEventListener()来移除移除时传入的参数与添加处理程序时使用的参数相同。通过 addEventListener()添加的匿名函数将无法移除,上面那种就是匿名函数,下面这种写法就能被移除:

    var btn = document.getElementById("myBtn");
    var handler = function(){
    alert(this.id);
    };
    btn.addEventListener("click", handler, false);
    btn.removeEventListener("click", handler, false);

    IE的事件注册

     attachEvent()和 detachEvent(),两个参数,可注册多个事件,但是事件触发顺序与注册顺序是相反的,都是在冒泡阶段被处理,且处理可程序里的this指向window。事件的移除中同样不能移除匿名函数

    IE事件注册与移除的全过程:

    var btn = document.getElementById("myBtn");
    var handler = function(){
    alert("Clicked");
    };
    btn.attachEvent("onclick", handler);
    btn.detachEvent("onclick", handler);

    阻止事件的默认行为

    w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;

    要阻止特定事件的默认行为,可以使用 preventDefault()方法,前提是事件对象event的属性 cancelable 设置为 true 。

    function preventDefa(e){ 
      if(window.event){ 
        //IE中阻止函数器默认动作的方式  
        window.event.returnValue = false;  
      } 
      else{ 
        //阻止默认浏览器动作(W3C)  
        e.preventDefault(); 
      }  
    } 

    例如,链接的默认行为就是在被单击时会导航到其 href 特性指定的 URL。如果你想阻止链接导航这一默认行为,那么通过链接的
    onclick 事件处理程序可以取消它,如下面的例子所示。

    var link = document.getElementById("myLink");
    link.onclick = function(event){
    event.preventDefault();
    };

    事件代理

    在JavaScript中,经常会碰到要监听列表中多项li的情形,假设我们有一个列表如下,要实现以下功能:当鼠标点击某一li时,alert输出该li的内容

    <ul id="list">
      <li id="item1">item1</li>
      <li id="item2">item2</li>
      <li id="item3">item3</li>
      <li id="item4">item4</li>
    </ul>

    一个办法是给每个li注册监听事件。

    另一个办法就是:把事件处理器添加到一个父级元素上,这样就避免了把事件处理器添加到多个子级元素上。

    事件代理机制

    事件代理用到了两个在JavaSciprt事件中两个特性:事件冒泡以及目标元素。使用事件代理,我们可以把事件处理器添加到一个元素上,等待一个事件从它的子级元素里冒泡上来,并且可以得知这个事件是从哪个元素开始的。


    事件代理实现

    第一步,找到目标元素

    function getEventTarget(e) {
      e = e || window.event;//事件对象
      return e.target || e.srcElement;
    }

    第二步,判断目标元素,进行相关操作

    function editCell(e){
               var target = getEventTarget(e);
               if(是否是目标元素)
               {
                    // DO SOMETHING WITH THE CELL
                }
    }

     事件代理推文:【翻译】谈 focus 和 blur 的事件代理

  • 相关阅读:
    redis使用
    ZooKeeper之service discovery
    Git环境配置
    Windows 下MySql Replication(复制)配置
    Django框架简介(MVC框架和MTV框架)
    ftp连接服务器失败||或者Xshell链接错误:Could notconnect to '192.168.18.128' (port 22): Connection failed
    git
    roles
    ansible 中的模块
    ansible 中的 playbook 模块
  • 原文地址:https://www.cnblogs.com/yaoyao-sun/p/7107675.html
Copyright © 2020-2023  润新知