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

溜溜球~


shushushu
551 声望31 粉丝