監聽div的resize

  簡單點說,就是:
     在被監聽的 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>

結果就是這樣子
clipboard.png

clipboard.png

溜溜球~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章