前端学习--JS入门(6) 事件冒泡/事件委托/获取元素位置

一、事件流

1.1 事件流的两个阶段

事件流是事件完整执行过程中的流动路径

捕获阶段:

Document ---> Element html ---> Element body ---> Element div

冒泡阶段:

Element div ---> Element body ---> Element html ---> Document

1.2 事件捕获 

从DOM的根元素执行事件(从外到里)

1.3 事件冒泡

当一个元素的事件被触发时,同样的事件会在该元素的所有祖先元素中依次被触发(从里到外)

只会触发所有父元素的同名事件

//第三个参数默认false -冒泡 如果是true -捕获
DOM对象.addEventListener(事件类型, 事件处理函数, 是否使用捕获机制)

1.4 阻止冒泡

默认有冒泡模式存在,事件容易影响到父级元素

//冒泡和捕获都可以阻止
事件对象.stopPropagation()
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father {
      width: 500px;
      height: 500px;
      background-color: pink;
    }

    .son {
      width: 200px;
      height: 200px;
      background-color: purple;
    }
  </style>
</head>

<body>
  <div class="father">
    <div class="son"></div>
  </div>
  <script>
    const fa = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 山东  济南  蓝翔   目标(pink老师)  捕获阶段
    //  蓝翔  济南   山东   冒泡阶段
    document.addEventListener('click', function () {
      alert('我是爷爷')
    })
    fa.addEventListener('click', function () {
      alert('我是爸爸')
    })
    son.addEventListener('click', function (e) {
      alert('我是儿子')
      // 组织流动传播  事件对象.stopPropagation()
      e.stopPropagation()
    })

  </script>
</body>

</html>

阻止元素默认行为

<a href="http://www.baidu.com">百度一下</a>
<script>
     const a = document.querySelector('a')
     a.addEventListener('click',function(e){
         //阻止a标签的默认跳转行为
         e.preventDefault()
     })
</script>

1.5 解绑事件

匿名函数无法被解绑

const btn = document.querySelector('button')
function fn(){
    alert('点击了')
}
btn.addEventListener('click', fn)
//解绑
btn.removeEventListener('click', fn)

1.6 鼠标经过事件

mouseover和mouseout有冒泡效果

mouseenter和mouseleave没有冒泡效果 (建议使用)

二、事件委托

同时给多个元素注册事件--利用事件冒泡

给父元素注册事件,当触发子元素时,会冒泡到父元素上,触发父元素的事件

//点击一个li所有的li都会变红        
const ul = document.querySelector('ul')
ul.addEventListener('click',function(){
     ul.style.color = 'red'
})
//点击的对象变色
const ul = document.querySelector('ul')
ul.addEventListener('click',function(e){
     e.target.style.color = 'red'
})
//指定事件响应的特定元素
const ul = document.querySelector('ul')
ul.addEventListener('click',function(e){
     if(e.target.tagName === 'LI'){
          e.target.style.color = 'red'
     }
})

 tab栏案例优化(去掉循环)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>tab栏切换</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .tab {
      width: 590px;
      height: 340px;
      margin: 20px;
      border: 1px solid #e4e4e4;
    }

    .tab-nav {
      width: 100%;
      height: 60px;
      line-height: 60px;
      display: flex;
      justify-content: space-between;
    }

    .tab-nav h3 {
      font-size: 24px;
      font-weight: normal;
      margin-left: 20px;
    }

    .tab-nav ul {
      list-style: none;
      display: flex;
      justify-content: flex-end;
    }

    .tab-nav ul li {
      margin: 0 20px;
      font-size: 14px;
    }

    .tab-nav ul li a {
      text-decoration: none;
      border-bottom: 2px solid transparent;
      color: #333;
    }

    .tab-nav ul li a.active {
      border-color: #e1251b;
      color: #e1251b;
    }

    .tab-content {
      padding: 0 16px;
    }

    .tab-content .item {
      display: none;
    }

    .tab-content .item.active {
      display: block;
    }
  </style>
</head>

<body>
  <div class="tab">
    <div class="tab-nav">
      <h3>每日特价</h3>
      <ul>
        <li><a class="active" href="javascript:;" data-id="0">精选</a></li>
        <li><a href="javascript:;" data-id="1">美食</a></li>
        <li><a href="javascript:;" data-id="2">百货</a></li>
        <li><a href="javascript:;" data-id="3">个护</a></li>
        <li><a href="javascript:;" data-id="4">预告</a></li>
      </ul>
    </div>
    <div class="tab-content">
      <div class="item active"><img src="./image/tab00.png" alt="" /></div>
      <div class="item"><img src="./image/tab01.png" alt="" /></div>
      <div class="item"><img src="./image/tab02.png" alt="" /></div>
      <div class="item"><img src="./image/tab03.png" alt="" /></div>
      <div class="item"><img src="./image/tab04.png" alt="" /></div>
    </div>
  </div>
  <script>
    const ul = document.querySelector('.tab-nav ul')
    ul.addEventListener('click', function(e){
      //mouseenter没有e.target对象 
      if(e.target.tagName === 'A'){
        document.querySelector('.tab-nav .active').classList.remove('active')
        console.log(e.target)
        e.target.classList.add('active')

        //获取自定义属性
        const id = e.target.dataset.id
        document.querySelector('.tab-content .active').classList.remove('active')
        //id过来是字符串 要转化成数字
        document.querySelector(`.tab-content .item:nth-child(${+id+1})`).classList.add('active')
      }
    })


  </script>
</body>

</html>

 三、其他事件

3.1 页面加载事件

外部资源加载完毕时触发的事件

//等待页面所有资源加载完毕 回去执行回调函数
//如果script标签写在head中

window.addEventListener('load',function(e){
    
})
//当html文档加载完之后 事件可以被触发
//比load更快
document.addEventListener('DOMContentLoaded',function(){

})

3.2 页面滚动事件

滚动条再滚动的时候持续触发的事件

应用:固定导航栏/返回顶部

window.addEventListener('scroll',function(e){
     console.log('我滚了');
})

scrollTop和scrollLeft 

被卷去的内容高度/内容宽度

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            height: 3000px;
        }
        div{
            opacity: 0;
            margin: 500px auto;
            height: 200px;
            width: 200px;
            background-color: pink;
            transition: all 0.5s;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
        window.addEventListener('scroll',function(e){
            //document.documentElement html元素的获取方式
            const n = document.documentElement.scrollTop
            const div = document.querySelector('div')
            if( n >= 200){
                div.style.opacity = '1'
            }
        })
    </script>
</body>
</html>

3.3 页面尺寸事件

//窗口尺寸改变时触发
window.addEventListener('resize',function(){

})

获取元素宽高

clientWidth / clientHeight

不包括border、margin、滚动条,包括padding

四、元素尺寸与位置

4.1 获取元素自身的宽高

包括padding、border、滚动条

offsetWidth / offsetHeight

获取到的是[可视宽高]

4.2 获取元素位置

元素距离自己定位父级元素的左、上距离(如果没有定位,就一直往上找到有定位的父元素)

offsetLeft / offsetTop 只读属性

4.3 获取元素相对于视口的位置

element.getBoundingClientRect()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值