监听div的resize

简单点说,就是:
     在被监听的 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>

结果就是这样子
clipboard.pngui

clipboard.png

溜溜球~spa

相关文章
相关标签/搜索