调整 div 元素的大小

IT技术 javascript jquery
2021-02-18 15:37:06

jQuery 有resize()- 事件,但它只适用于窗口。

jQuery(window).resize(function() { /* What ever */ });

这很好用!但是当我想将事件添加到 div 元素时,它不起作用。

例如

jQuery('div').resize(function() { /* What ever */ });

我想在 div 元素的大小发生变化时启动回调。我不想启动一个可调整大小的 - 事件 - 只是一个检查 div - 元素大小是否已更改的事件。

有没有办法做到这一点?

6个回答

DIV不会触发resize事件,因此您将无法完全执行您编写的代码,但您可以查看监控 DOM 属性

如果您实际上正在使用诸如可调整大小之类的东西,并且这是改变 div 大小的唯一方法,那么您的调整大小插件可能会实现自己的回调。

您可以使用 $(window).trigger("resize"); 触发窗口调整大小事件。
2021-04-24 15:37:06

我只对更改元素宽度时的触发器感兴趣(我不关心高度),所以我创建了一个 jquery 事件,它使用一个不可见的 iframe 元素来实现这一点。

$.event.special.widthChanged = {
  remove: function() {
      $(this).children('iframe.width-changed').remove();
  },
  add: function () {
      var elm = $(this);
      var iframe = elm.children('iframe.width-changed');
      if (!iframe.length) {
          iframe = $('<iframe/>').addClass('width-changed').prependTo(this);
      }
      var oldWidth = elm.width();
      function elmResized() {
          var width = elm.width();
          if (oldWidth != width) {
              elm.trigger('widthChanged', [width, oldWidth]);
              oldWidth = width;
          }
      }

      var timer = 0;
      var ielm = iframe[0];
      (ielm.contentWindow || ielm).onresize = function() {
          clearTimeout(timer);
          timer = setTimeout(elmResized, 20);
      };
  }
}

它需要以下 css :

iframe.width-changed {
    width: 100%;
    display: block;
    border: 0;
    height: 0;
    margin: 0;
}

你可以在这里看到它在行动中widthChanged fiddle

这是正确的答案。将事件附加到 iframe 的窗口比间隔要少得多。
2021-04-22 15:37:06
太棒了!我通过动态添加样式表使我的完全基于 js: var ss = document.createElement('style'); ss.type = "text/css"; ss.innerHTML = "iframe.width-changed {width: 100%;display: block;border: 0;height: 0;margin: 0;}"; document.body.appendChild(ss);
2021-05-04 15:37:06
是的,这是为了防止多次调用“widthChanged”触发器
2021-05-04 15:37:06
这是纯粹的天才。
2021-05-10 15:37:06
我即将使用它,但我想知道:计时器和 setTimeout 的作用是什么?当用户调整元素大小时,它是否像“去抖动”/节流阀以防止检测到太多调整大小?
2021-05-15 15:37:06
// this is a Jquery plugin function that fires an event when the size of an element is changed
// usage: $().sizeChanged(function(){})

(function ($) {

$.fn.sizeChanged = function (handleFunction) {
    var element = this;
    var lastWidth = element.width();
    var lastHeight = element.height();

    setInterval(function () {
        if (lastWidth === element.width()&&lastHeight === element.height())
            return;
        if (typeof (handleFunction) == 'function') {
            handleFunction({ width: lastWidth, height: lastHeight },
                           { width: element.width(), height: element.height() });
            lastWidth = element.width();
            lastHeight = element.height();
        }
    }, 100);


    return element;
};

}(jQuery));

我已经创建了 jquery 插件jquery.resize它使用 resizeObserver 如果支持或基于marcj/css-element-queries滚动事件的解决方案,没有 setTimeout/setInterval。

你只用

 jQuery('div').on('resize', function() { /* What ever */ });

或作为调整器插件

jQuery('div').resizer(function() { /* What ever */ });

我已经为 jQuery 终端创建了这个并提取到单独的 repo 和 npm 包中,但同时我切换到隐藏的 iframe,因为如果元素在 iframe 内,我在调整大小时遇到​​问题。我可能会相应地更新插件。您可以在 jQuery Terminal source code 中查看基于 iframe 的 resizer 插件

编辑:新版本使用 iframe 并调整其窗口对象的大小,因为当页面位于 iframe 内时,以前的解决方案不起作用。

EDIT2:因为回退使用 iframe 你不能将它与表单控件或图像一起使用,你需要将它添加到包装器元素。

EDIT3 ::使用resizeObserver polyfill有更好的解决方案,它使用变异观察器(如果不支持 resizeObserver)并且甚至在 IE 中也能工作。它还具有 TypeScript 类型。

那是个好主意。干得好,真的。
2021-04-16 15:37:06
为 EDIT3 欢呼吧。我被迫使用 IE11,这成功了,谢谢!
2021-04-28 15:37:06

那这个呢:

divH = divW = 0;
jQuery(document).ready(function(){
    divW = jQuery("div").width();
    divH = jQuery("div").height();
});
function checkResize(){
    var w = jQuery("div").width();
    var h = jQuery("div").height();
    if (w != divW || h != divH) {
        /*what ever*/
        divH = h;
        divW = w;
    }
}
jQuery(window).resize(checkResize);
var timer = setInterval(checkResize, 1000);

顺便说一句,我建议您在 div 中添加一个 id 并将 $("div") 更改为 $("#yourid"),这样会更快,并且以后添加其他 div 时不会中断

添加了 setInterval 的代码。您需要对其进行微调,因为 1000 毫秒对您来说可能太多了,另一方面,太低的数字很容易杀死您的 CPU。如果你知道你不需要再听了,那么调用: clearInterval(timer) !
2021-04-18 15:37:06
对!这就是我项目中的问题。div 元素位于具有 css 属性 Overflow:hidden 的外部包装器中 - 因此窗口不会更改大小。但在其他方面,该示例可以正常工作 - 我只是对其进行了测试。
2021-04-22 15:37:06
当然 - 这只是一个例子 - 当然我使用 id 和类来选择我的元素。我喜欢你的想法——我认为它会奏效!非常感谢。我会在几分钟内尝试并提供反馈。
2021-04-24 15:37:06
每当resize触发窗口的事件时,它都会监视 DIV 的大小变化很可能会改变 div 的大小而不会立即跟随窗口调整大小,在这种情况下/* what ever */不会评估部分。
2021-05-09 15:37:06
@Timo:$(window).resize通过例如拖动右下角来收听物理调整浏览器窗口大小的行为。没有什么 DOM 事件会触发这个事件,overflow:hidden或者不。这个答案没有解决你的问题。在计时器中运行此代码比附加到可能永远不会被触发的随机事件侦听器更有意义。如果您可以使用 DOM 属性监控并回退到计时器(或在 div 大小可以更改的地方手动引发一些事件),那就更好了。
2021-05-15 15:37:06