JS监听div的resize事件
原文地址:http://zhangyiheng.com/blog/articles/div_resize.html
需求
开发过程中经常遇到的一个问题就是如何监听一个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监听input值改变事件
哈哈哈,又来了,今天闲来无事,实验了下原生js监听input value值改变事件,下面就来说道说道: 本来写监听input值便获是用jquery的,之前的随笔写了,就是这个方法,地址:http:// ...
- ActiveX(二)Js 监听 ActiveX中的事件
在上一篇随笔:ActiveX(一)第一个简单的Demo 中,已经可以实现 js 单向调用 ActiveX 中的方法,在很多情况下ActiveX中的方法的执行时相对耗时.耗性能的.在这样的情况下.Act ...
- FineReport——JS监听其他控件事件
首先在参数面板和报表中分布添加一个button,用于被监听: 参数面板 控件名:temp: temp点击事件:alert("temp"); 报表 控件名:exprt: temp点击 ...
- js监听页面的scroll事件,当移到底部时触发事件
//页面拉到底时自动加载更多 $(window).scroll(function(event){ var wScrollY = window.scrollY; // 当前滚动条位置 var wInne ...
- js监听文本框变化事件
用js有两种写法: 法一: <!DOCTYPE HTMl> <html> <head> <title> new document </title& ...
- JS 监听绑定和取消事件
1. 原生 JS 语言: 绑定:addEventListener(type, function, false) 取消: removeEventListener(type, function, fals ...
- js监听全屏的事件
window.addEventListener('click',function(){ window.top.location.href = '../../loginOut.do'; //解决ifr ...
- js监听 window.open 关闭事件
转载自:http://blog.csdn.net/hanshileiai/article/details/41346729 首先创建一个新的对象,这将打开一个弹出这样的: var winObj = w ...
- js 监听整个页面的回车事件
JS监听整个页面的回车事件 <script type="text/javascript"> document.onkeydown=keyDownSearch; ...
随机推荐
- WebGIS开源解决方案之开发环境搭建(一)
工欲善其事,必先利其器,本文主要讲述WebGIS开源解决方案之环境搭建--geoserver的安装 安装方式一:tomcat环境下安装 从tomcat官网下载tomcat环境,下载链接:http:// ...
- linux用户和组的创建与管理!
useradd创建用户,usermod修改用户属性,userdel删除用户,groupadd创建组,groupmod修改组属性,groupdel删除组. 创建用户命令:useradd 语法: user ...
- 为Distinct准备的通用对比器
使用Linq过滤重复对象的时候,我们使用Distinct. 但是Distinct对int long等值类型才有效果,对于对象我们需要自己写个对象. 以下利用泛型封装了两个类: CommonCompar ...
- angular.js的ui-router总结
ui-route 先有个网址,再在这个网址下写路由 子路由的搭建 我们的布局/模板文件 index.html 我们通过建立一个主文件来引入我们所需要的所有资源以开始我们的项目 ,这里 ...
- 基于HTML5快速搭建TP-LINK电信拓扑设备面板
今天我们以真实的TP-LINK设备面板为模型,完成设备面板的搭建,和指示灯的闪烁和图元流动. 先来目睹下最终的实现效果:http://www.hightopo.com/demo/blog_tplink ...
- UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 22: invalid continuation byte
在使用python读取文本文件,一般会这样写: # -*- coding:utf-8 -*- f = open("train.txt", "r", encodi ...
- 获取JUnit的执行结果
junit执行之后会有一个结果展示,下面就来看一下怎么获取这些结果并将其存储为一个对象 junit代码如下: package test; import org.junit.After; import ...
- 一次基于Vue.Js用户体验的优化
.mytitle { background: #2B6695; color: white; font-family: "微软雅黑", "宋体", "黑 ...
- on方法使用注意事项
on(eventType,[childSelector],[data],fn) 采用事件委托机制绑定事件,好处是子元素动态加入时无需再次绑定. on方法可以传入childSelector指定添加事件处 ...
- 数据库安全性操作——操作原则及SQL注入
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6893134.html 今天在进行支付宝开发时,看到支付宝开发文档<开放平台第三方应用安全开发指南> ...