JS如何监听div的resize事件详解


Posted in Javascript onDecember 03, 2020

需求

开发过程中经常遇到的一个问题就是如何监听一个div的size变化。
比如我用canvas绘制了一个chart,当canvas的size发生变化的时候,需要重新绘制里面的内容,这个时候就需要监听resize事件做处理。

window上虽然可以添加resize事件监听,但这并不能满足我们的需求,因为很多时候,div的size发生了变化,但是window的size并没有改变。

不过我们可以间接利用window的resize事件监听来实现对于某个div的resize事件监听,请看下面具体实现。

对于div的resize事件的监听,实现方式有很多,比如周期性检查,通过scroll事件等等,本文主要介绍通过object元素来实现监听。

具体实现

/**
 * Created by taozh on 2017/5/6.
 * taozh1982@gmail.com
 */
var EleResize = {
 _handleResize: function (e) {
  var ele = e.target || e.srcElement;
  var trigger = ele.__resizeTrigger__;
  if (trigger) {
   var handlers = trigger.__z_resizeListeners;
   if (handlers) {
    var size = handlers.length;
    for (var i = 0; i < size; i++) {
     var h = handlers[i];
     var handler = h.handler;
     var context = h.context;
     handler.apply(context, [e]);
    }
   }
  }
 },
 _removeHandler: function (ele, handler, context) {
  var handlers = ele.__z_resizeListeners;
  if (handlers) {
   var size = handlers.length;
   for (var i = 0; i < size; i++) {
    var h = handlers[i];
    if (h.handler === handler && h.context === context) {
     handlers.splice(i, 1);
     return;
    }
   }
  }
 },
 _createResizeTrigger: function (ele) {
  var obj = document.createElement('object');
  obj.setAttribute('style',
   'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden;opacity: 0; pointer-events: none; z-index: -1;');
  obj.onload = EleResize._handleObjectLoad;
  obj.type = 'text/html';
  ele.appendChild(obj);
  obj.data = 'about:blank';
  return obj;
 },
 _handleObjectLoad: function (evt) {
  this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__;
  this.contentDocument.defaultView.addEventListener('resize', EleResize._handleResize);
 }
};
if (document.attachEvent) {//ie9-10
 EleResize.on = function (ele, handler, context) {
  var handlers = ele.__z_resizeListeners;
  if (!handlers) {
   handlers = [];
   ele.__z_resizeListeners = handlers;
   ele.__resizeTrigger__ = ele;
   ele.attachEvent('onresize', EleResize._handleResize);
  }
  handlers.push({
   handler: handler,
   context: context
  });
 };
 EleResize.off = function (ele, handler, context) {
  var handlers = ele.__z_resizeListeners;
  if (handlers) {
   EleResize._removeHandler(ele, handler, context);
   if (handlers.length === 0) {
    ele.detachEvent('onresize', EleResize._handleResize);
    delete ele.__z_resizeListeners;
   }
  }
 }
} else {
 EleResize.on = function (ele, handler, context) {
  var handlers = ele.__z_resizeListeners;
  if (!handlers) {
   handlers = [];
   ele.__z_resizeListeners = handlers;

   if (getComputedStyle(ele, null).position === 'static') {
    ele.style.position = 'relative';
   }
   var obj = EleResize._createResizeTrigger(ele);
   ele.__resizeTrigger__ = obj;
   obj.__resizeElement__ = ele;
  }
  handlers.push({
   handler: handler,
   context: context
  });
 };
 EleResize.off = function (ele, handler, context) {
  var handlers = ele.__z_resizeListeners;
  if (handlers) {
   EleResize._removeHandler(ele, handler, context);
   if (handlers.length === 0) {
    var trigger = ele.__resizeTrigger__;
    if (trigger) {
     trigger.contentDocument.defaultView.removeEventListener('resize', EleResize._handleResize);
     ele.removeChild(trigger);
     delete ele.__resizeTrigger__;
    }
    delete ele.__z_resizeListeners;
   }
  }
 }
}

测试代码:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Resize</title>
 <script src="./EleResize.js"></script>
 <style>
  html, body {
   margin: 0;
   padding: 0;
   width: 100%;
   height: 100%;
  }

  #resizeDiv {
   width: 60%;
   height: 60%;
   border: 1px solid red;
   margin: 20px;
  }

  button {
   margin: 20px 20px 0;
  }
 </style>
</head>
<body>
<button onclick="addListener()">addListener</button>
<button onclick="removeListener()">removeListener</button>
<button onclick="resize()">resize</button>
<div id="resizeDiv"></div>
<script>
 var resizeDiv = document.getElementById('resizeDiv');
 function resize() {
  resizeDiv.style.width = "200px";
 }
 var listener = function () {
  console.log("resize");
 };
 function addListener() {
  EleResize.on(resizeDiv, listener);
 }
 function removeListener() {
  EleResize.off(resizeDiv, listener)
 }
</script>
</body>
</html>

原理

这里的具体实现分两类,

  • ie9-10

默认支持div的resize事件,可以直接通过div.attachEvent('onresize', handler);的方式实现

  • 其它浏览器

通过在div中添加一个内置object元素实现监听。

设置object元素的style使其填充满div,这样当div的size发生变化时,object的size也会发生变化。

然后监听object元素的contentDocument.defaultView(window对象)的resize事件。

注:本文提供的是如何监听resize事件,其实在resize时,可能会连续快速的触发(比如拖动浏览器),为了提高效率,可以考虑使用批处理的模式。

到此这篇关于JS如何监听div的resize事件的文章就介绍到这了,更多相关JS监听div的resize事件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript检测浏览器flash版本的实现代码
Dec 06 Javascript
JavaScript函数详解
Nov 17 Javascript
js实现带关闭按钮始终显示在网页最底部工具条的方法
Mar 02 Javascript
微信小程序 列表的上拉加载和下拉刷新的实现
Apr 01 Javascript
微信小程序教程系列之视图层的条件渲染(10)
Apr 19 Javascript
JavaScript手风琴页面制作
May 17 Javascript
Vue 组件间的样式冲突污染
Aug 31 Javascript
JavaScript使用atan2来绘制箭头和曲线的实例
Sep 14 Javascript
jQuery实现可兼容IE6的遮罩功能详解
Sep 19 jQuery
微信小程序实现自定义modal弹窗封装的方法
Jun 15 Javascript
vue-cli3配置与跨域处理方法
Aug 17 Javascript
基于VUE实现简单的学生信息管理系统
Jan 13 Vue.js
JavaScript十大取整方法实例教程
Dec 03 #Javascript
js实现圆形菜单选择器
Dec 03 #Javascript
Javascript新手入门之字符串拼接与变量的应用
Dec 03 #Javascript
vue表单验证之禁止input输入框输入空格
Dec 03 #Vue.js
微信小程序实现首页弹出广告
Dec 03 #Javascript
为什么JavaScript中0.1 + 0.2 != 0.3
Dec 03 #Javascript
基于javascript实现放大镜特效
Dec 03 #Javascript
You might like
destoon网站转移服务器后搜索汉字出现乱码的解决方法
2014/06/21 PHP
Yii入门教程之目录结构、入口文件及路由设置
2014/11/25 PHP
php使用cookie实现记住用户名和密码实现代码
2015/04/27 PHP
Linux平台php命令行程序处理管道数据的方法
2016/11/10 PHP
PHP实现的简单留言板功能示例【基于thinkPHP框架】
2018/12/07 PHP
详解php伪造Referer请求反盗链资源
2019/01/24 PHP
javascript返回顶部效果(自写代码)
2013/01/06 Javascript
调用DOM对象的focus使文本框获得焦点
2014/02/19 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
js查看一个函数的执行时间实例代码
2015/09/12 Javascript
深入理解JS addLoadEvent函数
2016/05/20 Javascript
jQueryUI 拖放排序遇到滚动条时有可能无法执行排序的小bug及解决方案
2016/12/19 Javascript
JS常用知识点整理
2017/01/21 Javascript
浅谈vue中使用图片懒加载vue-lazyload插件详细指南
2017/10/23 Javascript
用Vue编写抽象组件的方法
2019/05/06 Javascript
vue 清空input标签 中file的值操作
2020/07/21 Javascript
python爬虫入门教程之点点美女图片爬虫代码分享
2014/09/02 Python
python smtplib模块发送SSL/TLS安全邮件实例
2015/04/08 Python
Python的Django框架中的URL配置与松耦合
2015/07/15 Python
详解Python的Django框架中的Cookie相关处理
2015/07/22 Python
解决Python内层for循环如何break出外层的循环的问题
2019/06/24 Python
python urllib爬虫模块使用解析
2019/09/05 Python
Python使用requests xpath 并开启多线程爬取西刺代理ip实例
2020/03/06 Python
python raise的基本使用
2020/09/10 Python
python smtplib发送多个email联系人的实现
2020/10/09 Python
关于PySnooper 永远不要使用print进行调试的问题
2021/03/04 Python
详解CSS3伸缩布局盒模型Flex布局
2018/08/20 HTML / CSS
唤醒头发毛囊的秘密武器:Grow Gorgeous
2016/08/28 全球购物
Chicco婴儿用品美国官网:汽车座椅、婴儿推车、高脚椅等
2018/11/05 全球购物
php优化查询foreach代码实例讲解
2021/03/24 PHP
《绿色蝈蝈》教学反思
2014/03/02 职场文书
法律专业求职信
2014/05/24 职场文书
2015年五四青年节演讲稿
2015/03/18 职场文书
学校德育工作总结2015
2015/05/11 职场文书
英语教学课后反思
2016/02/15 职场文书
《游戏王:大师决斗》新活动上线 若无符合卡组可免费租用
2022/04/13 其他游戏