我有下面的样本html,有一个DIV有100%的宽度。它包含了一些元素。在执行窗口调整大小时,内部元素可能会被重新定位,div的尺寸可能会改变。我在问是否有可能挂钩div的维度变化事件?以及如何做到这一点?我目前绑定回调函数到目标DIV上的jQuery调整大小事件,但是,没有输出控制台日志,如下所示:

<html>
<head>
    <script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
    <script type="text/javascript" language="javascript">
            $('#test_div').bind('resize', function(){
                console.log('resized');
            });
    </script>
</head>
<body>
    <div id="test_div" style="width: 100%; min-height: 30px; border: 1px dashed pink;">
        <input type="button" value="button 1" />
        <input type="button" value="button 2" />
        <input type="button" value="button 3" />
    </div>
</body>
</html>

当前回答

令人惊讶的是,尽管这个问题已经存在很久了,但在大多数浏览器中仍然存在这个问题。

正如其他人所说,Chrome 64+现在自带Resize observed,然而,该规范仍在微调中,Chrome目前(截至2019-01-29)落后于最新版本的规范。

我已经在野外看到了一些很好的ResizeObserver腻子,但是,一些没有严格遵循规范,另一些有一些计算问题。

我迫切需要这种行为来创建一些可以在任何应用程序中使用的响应式web组件。为了使他们工作得很好,他们需要随时知道他们的尺寸,所以ResizeObservers听起来很理想,我决定创建一个尽可能严格遵循规范的填充。

回购协议: https://github.com/juggle/resize-observer

演示: https://codesandbox.io/s/myqzvpmmy9

其他回答

ResizeSensor.js是一个巨大库的一部分,但我把它的功能简化为:

function ResizeSensor(element, callback)
{
    let zIndex = parseInt(getComputedStyle(element));
    if(isNaN(zIndex)) { zIndex = 0; };
    zIndex--;

    let expand = document.createElement('div');
    expand.style.position = "absolute";
    expand.style.left = "0px";
    expand.style.top = "0px";
    expand.style.right = "0px";
    expand.style.bottom = "0px";
    expand.style.overflow = "hidden";
    expand.style.zIndex = zIndex;
    expand.style.visibility = "hidden";

    let expandChild = document.createElement('div');
    expandChild.style.position = "absolute";
    expandChild.style.left = "0px";
    expandChild.style.top = "0px";
    expandChild.style.width = "10000000px";
    expandChild.style.height = "10000000px";
    expand.appendChild(expandChild);

    let shrink = document.createElement('div');
    shrink.style.position = "absolute";
    shrink.style.left = "0px";
    shrink.style.top = "0px";
    shrink.style.right = "0px";
    shrink.style.bottom = "0px";
    shrink.style.overflow = "hidden";
    shrink.style.zIndex = zIndex;
    shrink.style.visibility = "hidden";

    let shrinkChild = document.createElement('div');
    shrinkChild.style.position = "absolute";
    shrinkChild.style.left = "0px";
    shrinkChild.style.top = "0px";
    shrinkChild.style.width = "200%";
    shrinkChild.style.height = "200%";
    shrink.appendChild(shrinkChild);

    element.appendChild(expand);
    element.appendChild(shrink);

    function setScroll()
    {
        expand.scrollLeft = 10000000;
        expand.scrollTop = 10000000;

        shrink.scrollLeft = 10000000;
        shrink.scrollTop = 10000000;
    };
    setScroll();

    let size = element.getBoundingClientRect();

    let currentWidth = size.width;
    let currentHeight = size.height;

    let onScroll = function()
    {
        let size = element.getBoundingClientRect();

        let newWidth = size.width;
        let newHeight = size.height;

        if(newWidth != currentWidth || newHeight != currentHeight)
        {
            currentWidth = newWidth;
            currentHeight = newHeight;

            callback();
        }

        setScroll();
    };

    expand.addEventListener('scroll', onScroll);
    shrink.addEventListener('scroll', onScroll);
};

如何使用:

let container = document.querySelector(".container");
new ResizeSensor(container, function()
{
    console.log("dimension changed:", container.clientWidth, container.clientHeight);
});

使用disconnect删除事件监听器:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["input", "context", "output"]

  connect() {
    this.inputObserver = new ResizeObserver(() => { this.resizeInput() })
    this.inputObserver.observe(this.inputTarget)
  }

  disconnect() {
    this.inputObserver.disconnect(this.inputTarget)
  }

  resizeInput() {
    const height = this.inputTarget.offsetHeight

    this.contextTarget.style.height = `${height}px`
    this.outputTarget.style.height = `${height}px`
  }
}

您可以使用iframe或对象使用contentWindow或contentDocument调整大小。没有setInterval或setTimeout

的步骤:

将元素位置设置为相对位置 在里面添加一个透明的绝对隐藏IFRAME 听IFRAME。contentWindow - onresize事件

HTML的一个例子:

<div style="height:50px;background-color:red;position:relative;border:1px solid red">
<iframe style=width:100%;height:100%;position:absolute;border:none;background-color:transparent allowtransparency=true>
</iframe>
This is my div
</div>

Javascript:

$('div').width(100).height(100);
$('div').animate({width:200},2000);

$('object').attr({
    type : 'text/html'
})
$('object').on('resize,onresize,load,onload',function(){
    console.log('ooooooooonload')
})

$($('iframe')[0].contentWindow).on('resize',function(){
    console.log('div changed')
})

运行示例

JsFiddle: https://jsfiddle.net/qq8p470d/


看到更多:

粘土-它是基于元素-大小调整事件 element-resize-event

纯香草的实现。

var move = function(e) { if ((e.w && e.w !== e.offsetWidth) || (e.h && e.h !== e.offsetHeight)) { new Function(e.getAttribute('onresize')).call(e); } e.w = e.offsetWidth; e.h = e.offsetHeight; } var resize = function(e) { e.innerText = 'New dimensions: ' + e.w + ',' + e.h; } .resizable { resize: both; overflow: auto; width: 200px; border: 1px solid black; padding: 20px; } <div class='resizable' onresize="resize(this)" onmousemove="move(this)"> Pure vanilla implementation </div>

纯Javascript解决方案,但只有当元素用css resize按钮调整大小时才能工作:

使用offsetWidth和offsetHeight存储元素大小; 在这个元素上添加一个onclick事件监听器; 当触发时,比较当前的offsetWidth和offsetHeight与存储的值,如果不同,做你想做的,并更新这些值。