我有下面的样本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>

当前回答

看看这个http://benalman.com/code/projects/jquery-resize/examples/resize/

它有很多例子。尝试调整窗口大小,看看容器元素中的元素是如何调整的。

用js的例子来解释如何让它工作。 看看这小提琴http://jsfiddle.net/sgsqJ/4/

在这个resize()事件中,它被绑定到具有类“test”的元素以及窗口对象 在窗口对象$('.test')的resize回调中调用.resize()。

e.g.

$('#test_div').bind('resize', function(){
            console.log('resized');
});

$(window).resize(function(){
   $('#test_div').resize();
});

其他回答

最好的解决方案是使用所谓的元素查询。然而,它们不是标准的,没有规范存在——如果你想这样做,唯一的选择是使用一个可用的腻子库/库。

The idea behind element queries is to allow a certain container on the page to respond to the space that's provided to it. This will allow to write a component once and then drop it anywhere on the page, while it will adjust its contents to its current size. No matter what the Window size is. This is the first difference that we see between element queries and media queries. Everyone hopes that at some point a specification will be created that will standardize element queries (or something that achieves the same goal) and make them native, clean, simple and robust. Most people agree that Media queries are quite limited and don't help for modular design and true responsiveness.

有一些腻子/库可以用不同的方式解决这个问题(可以称为变通方案而不是解决方案):

CSS元素查询- https://github.com/marcj/css-element-queries BoomQueries - https://github.com/BoomTownROI/boomqueries eq.js - https://github.com/Snugug/eq.js ElementQuery - https://github.com/tysonmatanich/elementQuery 还有一些,我不打算在这里列出,但你可以自由搜索。我不能说目前可用的选项中哪一个是最好的。你得试几样再决定。

我看到过针对类似问题提出的其他解决方案。通常他们使用计时器或窗口/视口大小,这不是一个真正的解决方案。此外,我认为理想情况下,这个问题应该主要用CSS来解决,而不是javascript或html。

从长远来看,您将能够使用ResizeObserver。

new ResizeObserver(callback).observe(element);

不幸的是,目前许多浏览器默认不支持它。

同时,您可以像下面这样使用函数。因为,大部分元素大小的变化将来自窗口大小的调整或DOM中的某些更改。你可以通过窗口的resize事件来监听窗口的大小调整,也可以使用MutationObserver监听DOM的变化。

下面是一个函数的例子,当提供的元素的大小因为这两个事件中的任何一个而改变时,它会回调你:

var onResize = function(element, callback) {
  if (!onResize.watchedElementData) {
    // First time we are called, create a list of watched elements
    // and hook up the event listeners.
    onResize.watchedElementData = [];

    var checkForChanges = function() {
      onResize.watchedElementData.forEach(function(data) {
        if (data.element.offsetWidth !== data.offsetWidth ||
            data.element.offsetHeight !== data.offsetHeight) {
          data.offsetWidth = data.element.offsetWidth;
          data.offsetHeight = data.element.offsetHeight;
          data.callback();
        }
      });
    };

    // Listen to the window's size changes
    window.addEventListener('resize', checkForChanges);

    // Listen to changes on the elements in the page that affect layout 
    var observer = new MutationObserver(checkForChanges);
    observer.observe(document.body, { 
      attributes: true,
      childList: true,
      characterData: true,
      subtree: true 
    });
  }

  // Save the element we are watching
  onResize.watchedElementData.push({
    element: element,
    offsetWidth: element.offsetWidth,
    offsetHeight: element.offsetHeight,
    callback: callback
  });
};

这是一个非常老的问题,但我想我会把我的解决方案贴出来。

我尝试使用resizsensor,因为每个人似乎都对它有很大的好感。在实现之后,我意识到在底层,元素查询要求所讨论的元素具有相对位置或绝对位置,这不适用于我的情况。

我最终用Rxjs间隔来处理这个问题,而不是像以前的实现那样直接使用setTimeout或requestAnimationFrame。

间隔的可观察对象的好处在于,你可以修改流,但任何其他可观察对象都可以被处理。对我来说,一个基本的实现就足够了,但是你可以疯狂地做各种各样的合并等等。

在下面的例子中,我正在跟踪内部(绿色)div的宽度变化。它的宽度设置为50%,但max-width为200px。拖动滑块会影响包装器(灰色)div的宽度。你可以看到,只有当内部div的宽度发生变化时,可观察对象才会触发,只有当外部div的宽度小于400px时才会发生这种情况。

const { interval } = rxjs; const { distinctUntilChanged, map, filter } = rxjs.operators; const wrapper = document.getElementById('my-wrapper'); const input = document.getElementById('width-input'); function subscribeToResize() { const timer = interval(100); const myDiv = document.getElementById('my-div'); const widthElement = document.getElementById('width'); const isMax = document.getElementById('is-max'); /* NOTE: This is the important bit here */ timer .pipe( map(() => myDiv ? Math.round(myDiv.getBoundingClientRect().width) : 0), distinctUntilChanged(), // adding a takeUntil(), here as well would allow cleanup when the component is destroyed ) .subscribe((width) => { widthElement.innerHTML = width; isMax.innerHTML = width === 200 ? 'Max width' : '50% width'; }); } function defineRange() { input.min = 200; input.max = window.innerWidth; input.step = 10; input.value = input.max - 50; } function bindInputToWrapper() { input.addEventListener('input', (event) => { wrapper.style.width = `${event.target.value}px`; }); } defineRange(); subscribeToResize(); bindInputToWrapper(); .inner { width: 50%; max-width: 200px; } /* Aesthetic styles only */ .inner { background: #16a085; } .wrapper { background: #ecf0f1; color: white; margin-top: 24px; } .content { padding: 12px; } body { font-family: sans-serif; font-weight: bold; } <script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script> <h1>Resize Browser width</h1> <label for="width-input">Adjust the width of the wrapper element</label> <div> <input type="range" id="width-input"> </div> <div id="my-wrapper" class="wrapper"> <div id="my-div" class="inner"> <div class="content"> Width: <span id="width"></span>px <div id="is-max"></div> </div> </div> </div>

纯香草的实现。

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>

您必须将resize事件绑定到窗口对象上,而不是绑定到通用html元素上。

然后你可以使用这个:

$(window).resize(function() {
    ...
});

在回调函数中,你可以检查div调用的新宽度

$('.a-selector').width();

因此,您的问题的答案是否定的,您不能将resize事件绑定到div。