简单点说,就是: 在被监听的 div 中添加 iframe 标签,设置其高宽均为 100%; 在 iframe 的 resize 被触发时,则代表 div 的大小正在改变!
Resize on div element 来源于stackoverflow 的回答html
平常开发中,遇到元素宽高改变时须要广播事件,因为此时窗口大小并未改变,故添加resize回调没用;并且该元素是由于某些dom隐藏,其高宽自适应所致使,而不是经过js设置,故 MutationObserver 也没法监听到。
上网找了找,对于div的resize事件的监听,实现方式有不少,好比:jquery
基于jquery的小插件
经过object元素进行监听
scroll来监听元素resize
基于requestanimationframe的周期性检查git
虽然是实现了对元素宽高的监听,但看上去很瓜。直到看到了stackoverflow 的回答...github
这是咱们要监听的元素和样式app
<style> .container { position: relative; width: 500px; height: 300px; background-color: black; } </style> <div class="container"></div>
模拟resize的函数,参数el为被监听的元素,cb为回调函数dom
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>
结果就是这样子ui
溜溜球~spa