簡單點說,就是:
在被監聽的 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>
結果就是這樣子
溜溜球~