简单点说,就是:
在被监听的 div 中添加 iframe 标签,设置其高宽均为 100%;
在 iframe 的 resize 被触发时,则表明 div 的大小正在改变!
参考
Resize on div element 来源于stackoverflow 的回答
历程
日常开发中,遇到元素宽高改变时需要广播事件,由于此时窗口大小并未改变,故添加resize回调没用;而且该元素是因为某些dom隐藏,其高宽自适应所导致,而不是通过js设置,故 MutationObserver 也无法监听到。
上网找了找,对于div的resize事件的监听,实现方式有很多,比如:
基于jquery的小插件
通过object元素进行监听
scroll来监听元素resize
基于requestanimationframe的周期性检查
虽然是实现了对元素宽高的监听,但看上去很瓜。直到看到了stackoverflow 的回答...
代码
这是我们要监听的元素和样式
<style>
.container {
position: relative;
width: 500px;
height: 300px;
background-color: black;
}
</style>
<div class="container"></div>
模拟resize的函数,参数el为被监听的元素,cb为回调函数
function riseze (el, cb) {
// 创建iframe标签,设置样式并插入到被监听元素中
var iframe = document.createElement(‘iframe‘);
iframe.setAttribute(‘class‘, ‘size-watch‘);
el.appendChild(iframe);
// 记录元素当前宽高
var oldWidth = el.offsetWidth;
var oldHeight = el.offsetHeight;
// iframe 大小变化时的回调函数
function sizeChange () {
// 记录元素变化后的宽高
var width = el.offsetWidth;
var height = el.offsetHeight;
// 不一致时触发回调函数 cb,并更新元素当前宽高
if (width !== oldWidth || height !== oldHeight) {
cb({width: width, height: height}, {width: oldWidth, height: oldHeight});
oldWidth = width;
oldHeight = height;
}
}
// 设置定时器用于节流
var timer = 0;
// 将 sizeChange 函数挂载到 iframe 的resize回调中
iframe.contentWindow.onresize = function () {
clearTimeout(timer);
timer = setTimeout(sizeChange, 20);
};
}
这边是iframe的样式
.size-watch {
width: 100%;
height: 100%;
position: absolute;
visibility:hidden;
margin: 0;
padding: 0;
border: 0;
}
测试
试一哈...
<script>
var el = document.querySelector(‘.container‘);
riseze(el, (val, oldVal) => {
console.log(`size changed!new: ${JSON.stringify(val)}, old: ${JSON.stringify(oldVal)}`);
});
</script>
结果就是这样子
溜溜球~