事件流 事件冒泡和事件捕获

事件冒泡和事件捕获

他们是描述事件触发时序问题的术语。

DOM标准规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从外部到内部。 
冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从内部到外部

事件冒泡

<body>
  <div class="parent">
    <div class="son">
      <div class="grandson"></div>
    </div>

  </div>
  <script src="../report/js/jquery.min.js"></script>
  <script>
    $(‘.parent‘).click(function(){
      console.log(‘父‘)
    })
    $(‘.son‘).click(function(){
      console.log(‘子‘)
    })
    $(‘.grandson‘).click(function(){
      console.log(‘孙子‘)
    })
  </script>
</body>
</html>

事件冒泡 父子都绑定了事件,点击子元素,会触发子元素绑定的事件;同时也会触发父元素绑定的事件

    // 当点击 parent不与son grandson相交区域              打印结果为  父
    // 当点击 parent与son相交 而不与grandson相交区域       打印结果为  子-父
    // 当点击 parent  son grandson 三者相交区域           打印结果为  孙子-子-父
    // 这是因为 事件的触发顺序自内向外,这就是事件冒泡。

    // 若是在grandson 加上阻止事件冒泡
    // $(‘.grandson‘).click(function(e){
    //   console.log(‘孙子‘)
    //   e.stopPropagation()
    // })
    // 此时当点击 parent  son grandson 三者相交区域        打印结果为  孙子
    // 因为 e.stopPropagation() 阻止了冒泡向 son grandson 触发事件

由于一些人会以为显示出来儿子在父亲里面的时候,自然点了儿子相当于点了父亲,所以这个例子我故意把两个盒子绝对定位在了两个不同的位置,所以点击事件给页面显示出来的位置是没关系的,而是跟html代码中的位置有关系。

使用绝对定位,把parent、son、grandson分别定位到互不重叠的地区,点击grandson       打印的结果依然为孙子-子-父

<body>
  <div class="parent" id="parent">
    <div class="son" id="son">
      <div class="grandson" id="grandson"></div>
    </div>

  </div>
  <script src="../report/js/jquery.min.js"></script>
  <script>

    // var parent = document.getElementsByClassName(‘parent‘)
    // var son=document.getElementsByClassName(‘son‘)
    // var grandson=document.getElementsByClassName(‘grandson‘)

    var parent = document.getElementById(‘parent‘)
    var son=document.getElementById(‘son‘)
    var grandson=document.getElementById(‘grandson‘)

    parent.addEventListener(‘click‘,function(){
      console.log(‘父‘)
    },false)
    son.addEventListener(‘click‘,function(){
      console.log(‘子‘)
    },false)
    grandson.addEventListener(‘click‘,function(){
      console.log(‘孙子‘)
    },false)
  </script>
</body>

使用事件监听  默认为false是事件冒泡和jquey onclick一样也是默认事件冒泡

点击 grandson时,打印结果 孙子-子-父

注意:

    var parent1 = document.getElementsByClassName(‘parent‘)
    console.log(parent1)
    // 打印结果:HTMLCollection [div#parent.parent, parent: div#parent.parent]

    var parent2 = document.getElementById(‘parent‘)
    console.log(parent2)
    // 打印结果:<div class=‘parent‘ id=‘parent‘>...</div>
    parent1.addEventListener(‘click‘,function(){
      console.log(‘结果1‘)
    },false)
    // 结果报错 Uncaught TypeError: parent1.addEventListener is not a function

    parent2.addEventListener(‘click‘,function(){
      console.log(‘结果2‘)
    },false)
    //使用getElementById能正确打印出结果2

使用jquey 和js 获取元素的不同

  <script>
    var parentid=$(‘#parent‘)
    console.log(parentid)
    // 打印结果 r.fn.init [div#parent.parent]

    var parentclass=$(‘.parent‘)
    console.log(parentclass)
    // 打印结果 r.fn.init [div#parent.parent, prevObject: r.fn.init(1)]

    var parent_js_id=document.getElementById(‘parent‘)
    console.log(parent_js_id)
    // 打印结果 <div class="parent" id="parent">....</div>

    var parent_js_class=document.getElementsByClassName(‘parent‘)
    console.log(parent_js_class)
    // 打印结果 HTMLCollection [div#parent.parent, parent: div#parent.parent]
  </script>

事件捕获

  <script>
    var parent = document.getElementById(‘parent‘)
    var son=document.getElementById(‘son‘)
    var grandson=document.getElementById(‘grandson‘)

    parent.addEventListener(‘click‘,function(){
      console.log(‘父‘)
    },true)
    son.addEventListener(‘click‘,function(){
      console.log(‘子‘)
    },true)
    grandson.addEventListener(‘click‘,function(){
      console.log(‘孙子‘)  

    },true)

    // 改为true时 ,使用的是事件捕获 由外向内
    // 点击  parent 时               打印结果 父
    // 点击  son 时                  打印结果 父-子
    // 点击  grandson时              打印结果 父-子-孙子

    // 也能使用e.stopPropagation()
    // parent.addEventListener(‘click‘,function(){
    //   console.log(‘父‘)
    // },true)
    // son.addEventListener(‘click‘,function(e){
    //   console.log(‘子‘)
    //   e.stopPropagation()
    // },true)
    // grandson.addEventListener(‘click‘,function(){
    //   console.log(‘孙子‘)  

    // },true)
    // 当点击 grandson时  不使用stopPropagation()    打印结果 父-子-孙子
    // 当点击 grandson时  使用stopPropagation()      打印结果 父-子
  </script>

return false

javascript的return false只会阻止默认行为,而是用jQuery的话则既阻止默认行为又防止对象冒泡。

<body>
  <div class="parent" id="parent">
    <div class="son" id="son">
      <div class="grandson" id="grandson">
        <a id="click" href="https://baidu.com">点击</a>
      </div>
    </div>

  </div>
  <script src="../report/js/jquery.min.js"></script>
  <script>
    $(‘.parent‘).click(function(){
      console.log(‘父‘)
    })
    $(‘.son‘).click(function(){
      console.log(‘子‘)
    })
    $(‘.grandson‘).click(function(){
      console.log(‘孙子‘)
    })
    // jq
    $(‘#click‘).click(function(){
      console.log(‘jq点击‘)
      // 在jq中使用 return false  即阻止默认行为,又阻止冒泡
      return false
    })  //和上面同样效果
    // $(‘#click‘).on(‘click‘,function(){
    //   console.log(‘点击‘)      打印结果  点击-孙子-子-父  不会执行a标签的跳转
    //   return false
    // })

    // js
    var a=document.getElementById(‘click‘)
    a.onclick=function(){
      console.log(‘点击‘)
      return false                 //打印结果  点击-孙子-子-父  不会执行a标签的跳转
    }
    // document.getElementById(‘click‘).addEventListener(‘click‘,function(){
    //   console.log(‘点击‘)
    //   return false             //打印结果   return false不执行 ?????
    // })

  </script>

兼容不同浏览器的阻止事件冒泡和阻止默认行为

阻止事件冒泡

function stopBubble(e) {
//如果提供了事件对象,则这是一个非IE浏览器
if ( e && e.stopPropagation )
    //因此它支持W3C的stopPropagation()方法
    e.stopPropagation();
else
    //否则,我们需要使用IE的方式来取消事件冒泡
    window.event.cancelBubble = true;
}

阻止事件默认行为

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

preventDefault它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。既然是说默认行为,当然是元素必须有默认行为才能被取消,如果元素本身就没有默认行为,调用当然就无效了。什么元素有默认行为呢?如链接<a>,提交按钮<input type=”submit”>等。当Event 对象的 cancelable为false时,表示没有默认行为,这时即使有默认行为,调用preventDefault也是不会起作用的。

事件注意点

  1. event代表事件的状态,例如触发event对象的元素、鼠标的位置及状态、按下的键等等;
  2. event对象只在事件发生的过程中才有效。

firefox里的event跟IE里的不同,IE里的是全局变量,随时可用;firefox里的要用参数引导才能用,是运行时的临时变量。
在IE/Opera中是window.event,在Firefox中是event;而事件的对象,在IE中是window.event.srcElement,在Firefox中是event.target,Opera中两者都可用。

下面两句效果相同:

function a(e){
    var e = (e) ? e : ((window.event) ? window.event : null);
    var e = e || window.event; // firefox下window.event为null, IE下event为null
}

由于jq中已经封装好的代码,可以直接使用jq来兼容不同浏览器

绑定事件

事件绑定常用三种方法

1.嵌入到dom上

<body>
  <div onclick="btnOpen()">按钮</div>
  <script src="../report/js/jquery.min.js"></script>
  <script>
    function btnOpen(){
        alert(1)
    }
  </script>
</body>

ps 使用系统定义的关键字来为函数命名,无效。

<body>
  <div onclick="open()">按钮</div>
  <script src="../report/js/jquery.min.js"></script>
  <script>
    function open(){
        alert(1)
    }
  </script>
</body>

2.直接绑定

<body>
  <div id="btn">按钮</div>
  <script src="../report/js/jquery.min.js"></script>
  <script>
    document.getElementById(‘btn‘).onclick(function(){
      console.log(‘点击‘)
    })
  </script>
</body>

3.事件监听

<body>
  <div id="btn">按钮</div>
  <script src="../report/js/jquery.min.js"></script>
  <script>
    document.getElementById(‘btn‘).addEventListener(‘click‘,function(){
      console.log(‘按钮‘)
    })

  </script>
</body>
    // addEventListener(event, function, useCapture)
    //  event 事件名      function 事件触发执行的函数
    // useCapture 默认为false 事件在冒泡阶段执行    true 事件在捕获阶段执行

原文地址:https://www.cnblogs.com/zjx304/p/10032329.html

时间: 2024-07-29 15:27:58

事件流 事件冒泡和事件捕获的相关文章

js事件流机制冒泡和捕获

JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间. 事件流 从页面中接收事件的顺序称为事件流. IE --> 事件冒泡流 Netscape --> 事件捕获流 查看源码:DOM2事件-捕获-冒泡 事件冒泡 IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档). 我们先来个简单的例子,这是HTML结构 <!DOCTYP

事件流,冒泡,捕获,事件委托

js里怎么去监听一个事件? 网页中每一个元素都有可以产生某些触发JavaScript函数的事件,事件是可以被JavaScript侦测到的一种行为 监听方法的参数分别代表什么意思?其中哪些参数关系到js的事件流机制?js事件流机制有哪些工作?工作原理是什么? 第一个参数是,事件类型,例如onclick 第二个参数是,响应的时候所执行的函数 第三个是事件流问题,侦听的三个阶段,捕获阶段 --- 目标阶段 --- 冒泡阶段 此处的参数确定侦听器是运行于捕获,目标还是冒泡 如果将useCapture设置

位置信息 事件流概念 jquery的事件

jQuery 位置信息 jQuery位置信息就是一系列封装好的api. 一.高度和宽度 获取高度 .width 设置高度 .width() 获取宽度 .heigth 设置高度 .heigth 二.innerwidth .innerheigth 获取内部宽 .innerwidth() 设置内部宽 .innerwidth(value) 获取内部高 .innerheigth 获取内部宽 .innerheigth(value) 三 .outwidth. outheigth 获取外部宽 .outwidth

Dom事件流、冒泡、捕获

Dom事件流 dom的结构是一个倒立的树状结构.当一个html元素触发事件时,事件会在dom的根节点和触发事件的元素节点之间传播,中间的节点都会收到该事件. 捕获:div元素触发事件时,事件先从根节点document→html→body→div这个顺序传播.(给这四个节点绑定事件,事件依次触发的顺序): 冒泡:div元素触发事件时,事件从div→body→html→document这个顺序传播. dom事件流:先捕获,再冒泡.从document开始,到document结束形成一个完整的事件流.

javaScript事件(一)事件流

一.事件 事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字.事件是javaScript和DOM之间的桥梁.你若触发,我便执行——事件发生,调用它的处理函数执行相应的JavaScript代码给出响应.典型的例子有:页面加载完毕触发load事件:用户单击元素,触发click事件. 二.事件流 1.事件流感性认识问题:单击页面元素,什么样的元素能感应到这样一个事件?答案:单击元素的同时,也单击了元素的容器元素,甚至整个页面.例子:有三个同心圆, 给每个圆添

javaScript事件流是什么?

一.事件 事件是文档或者浏览器窗口中发生的,特定的交互瞬间. 事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字. 事件是javaScript和DOM之间交互的桥梁. 你若触发,我便执行--事件发生,调用它的处理函数执行相应的JavaScript代码给出响应. 典型的例子有:页面加载完毕触发load事件:用户单击元素,触发click事件. 二.事件流 事件流描述的是从页面中接收事件的顺序. 1.事件流感性认识 问题:单击页面元素,什么样的元素能感应到这

JavaScript——事件流(事件冒泡和事件捕获)

1.事件流 当浏览器发展到第4代时,浏览器开发团队遇到了一个问题:页面中的哪个元素会拥有某个特定的事件?当你单击某个按钮时,显然该单击事件并不仅仅发生在按钮上,它还发生在按钮的所有祖先元素上,比如按钮的容器元素,容器元素的父元素,甚至整个页面document.但是,哪个元素最先接收到该事件呢?页面接收事件的顺序又是怎样的呢?由此引出了事件流的概念.事件流描述的就是从页面中接收事件的顺序. 2.两个模型 Netscape和Microsoft给出了两个不同的结论.Netscape说document会

JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获

先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>JavaScript 中的事件冒泡与事件捕获</title> </head> <body> <div id="Red" style="width:200px;height:200px;background-color:red;padding:2

关于事件流,事件冒泡和事件捕获

1.事件流 假设有这样一个场景: 有一个导航条:div > ul > li > a,每个元素块宽高一样,就像是一组同心圆.如果我们点击a元素,那么浏览器会认为单击事件不仅仅发生在a上.换句话说,在我们单击a元素的同事,我们也单击了容器中的其他元素. 事件流描述的是从页面中接收事件的顺序.但有意思的是,IE 和 Netscape 却分别提出了不一样的事件流概念.IE 的事件流是事件冒泡,而Netscape的事件流是事件捕获流. 那么问题来了,什么是事件冒泡?什么是事件捕获? 2.事件冒泡

js事件捕获,事件冒泡,事件委托以及DOM事件流

一:DOM事件流: 事件流是从页面接收事件的顺序,DOM2级事件规定事件流包括三个阶段: ①事件捕获阶段:用意在于事件达到目标之前捕获它,在事件捕获阶段事件流模型:document→html→body→div ②处于目标阶段2:实际的目标到事件 ③事件冒泡阶段:由最具体的元素接收到事件,然后向上传播到较为不具体的节点.事件流模型:div →body→ html→ document 二:事件委托 事件委托顾名思义:将事件委托给另外的元素.其实就是利用DOM的事件冒泡原理,将事件绑定到目标元素的父节