为网页元素增加resize事件

4 篇文章 0 订阅
3 篇文章 0 订阅
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
       html,body {
           width: 100%;
           height: 100%;
       }
      .resize {
          width: 40%;
          height: 40%;
          background-color: aqua;
      }
    </style>
</head>
<div class="resize"></div>
<body>
    <script>
    // 为网页元素增加resize事件
    // 默认只有window支持resize事件,但有时我们需要为div等元素添加resize事件
    // 代码见下面,原理是在元素内添加一个内嵌html,然后监听这个内嵌html的resize事件
    // pointer-events: none 元素永远不会成为鼠标事件的target。但是,当其后代元素的pointer-events属性指定其他值时,
    // 鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶触发父元素的事件侦听器。
    class ResizeEventService {
       constructor() {
           this.isIE = /Trident/.test(navigator.userAgent)
       }
       addResizeListener(element, fn) {
           const self = this
           if (!element._resizeListeners_ || !element._resizeListeners_.length) {
               element._resizeListeners_ = []
               if (getComputedStyle(element).position === 'static') {
                   element.style.position = 'relative'
               }
               const obj = element._resizeTrigger_ = document.createElement('object')
               obj.setAttribute('style', `
               display: block; position: absolute; top: 0px; left: 0px; height: 100%;
               width: 100%; overflow: hidden; pointer-events: none; z-index: -1;
               `)
               obj._resizeElement = element
               // contentDocumnet 拿到文档对象模型
               // defaultView 拿到文档对象模型关联的对象模型
               obj.onload = function () {
                   this.contentDocument.defaultView._resizeTrigger_ = this._resizeElement
                   this.contentDocument.defaultView.addEventListener('resize', self.resizeListener)
               }
               obj.type = 'text/html'
               if (this.isIE) {
                   element.appendChild(obj)
               }
               obj.data = 'about: blank'
               if (!this.isIE) {
                   element.appendChild(obj)
               }
           }
           element._resizeListeners_.push(fn)
       }
       removeResizeListener(element, fn) {
           if (!element._resizeListeners_) {
               return
           }
           element._resizeListeners_.splice(element._resizeListeners_.indexOf(fn), 1)
           if (!element._resizeListeners_.length) {
               element._resizeTrigger_.contentDocument.defaultView.removeEventListener('resize',this.resizeListener)
               element._resizeTrigger_ = !element.removeChild(element._resizeTrigger_)
           }
       }
       resizeListener(e) {
           const win = e.target || e.srcElement
           if (win._resizeRAF_) {
               window.cancelAnimationFrame(win._resizeRAF_)
           }
           win._resizeRAF_ = window.requestAnimationFrame(function() {
               const trigger = win._resizeTrigger_
               trigger._resizeListeners_.forEach(fn => {
                   fn.call(trigger, e)
               });
           })
       }
    }
    let resize = new ResizeEventService()
    resize.addResizeListener(document.querySelector('.resize'), (e) => {
        console.log(e)
    })
    </script>
</body>
</html>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值