87

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

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

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

例如

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

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

有什么解决方案可以做到这一点吗?

4

13 回答 13

35

DIV不会触发resize事件,因此您将无法完全按照您的编码进行操作,但您可以查看监控 DOM 属性

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

于 2012-04-10T10:08:10.440 回答
34

我只对元素的宽度发生变化时的触发器感兴趣(我不关心高度),所以我使用不可见的 iframe 元素创建了一个执行此操作的 jquery 事件。

$.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

于 2014-09-27T17:07:03.967 回答
22
// 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));
于 2015-06-10T16:08:31.367 回答
8

我创建了 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 终端源代码中查看基于 iframe 的调整大小插件

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

EDIT2:因为后备使用 iframe,您不能将其与表单控件或图像一起使用,您需要将其添加到包装器元素中。

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

于 2018-05-08T15:58:32.183 回答
6

那这个呢:

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 时它不会中断

于 2012-04-10T10:11:38.447 回答
5

对于今年发布的基本 JavaScript 和 jQuery,有一个非常好的、易于使用、轻量级(使用本机浏览器事件进行检测)的插件。它表现完美:

https://github.com/sdecima/javascript-detect-element-resize

于 2014-09-04T17:16:07.763 回答
2

是的,仅支持窗口,但您可以使用插件:http ://benalman.com/projects/jquery-resize-plugin/

于 2012-04-10T10:07:16.107 回答
1

现在存在Resize Observer

你可以像这样使用它:

const resizeObserver = new ResizeObserver((entries) => {
  entries.forEach(console.log);
})
resizeObserver.observe(document.getElementById("ExampleElement"));
于 2021-08-31T03:24:22.943 回答
0

对于谷歌地图集成,我正在寻找一种方法来检测 div 的大小何时发生变化。由于谷歌地图总是需要适当的尺寸,例如宽度和高度才能正确渲染。

我想出的解决方案是一个事件的委托,在我的例子中是一个标签点击。当然,这可能是一个窗口调整大小,想法保持不变:

if (parent.is(':visible')) {
    w = parent.outerWidth(false);
    h = w * mapRatio /*9/16*/;
    this.map.css({ width: w, height: h });
} else {
    this.map.closest('.tab').one('click', function() {
        this.activate();
    }.bind(this));
}

this.map在这种情况下是我的地图 div。由于我的父母在加载时不可见,因此计算出的宽度和高度为 0 或不匹配。通过使用.bind(this),我可以将脚本执行 ( this.activate) 委托给事件 ( click)。

现在我相信这同样适用于调整大小事件。

$(window).one('resize', function() {
    this.div.css({ /*whatever*/ });
}.bind(this));

希望它可以帮助任何人!

于 2014-07-29T15:11:24.163 回答
0

试试这个函数(它可能不仅适用于 div):

function resized(elem, func = function(){}, args = []){
    elem = jQuery(elem);
    func = func.bind(elem);
    var h = -1, w = -1;
    setInterval(function(){
        if (elem.height() != h || elem.width() != w){
            h = elem.height();
            w = elem.width();
            func.apply(null, args);
        }
    }, 100);
}

你可以像这样使用它

resized(/*element*/ '.advs-columns-main > div > div', /*callback*/ function(a){
    console.log(a);
    console.log(this); //for accessing the jQuery element you passed
}, /*callback arguments in array*/ ['I\'m the first arg named "a"!']);

更新: 您还可以使用更先进的观察者(它可以用于任何对象,不仅是 DOM 元素):

function changed(elem, propsToBeChanged, func = function(){}, args = [], interval = 100){
        func = func.bind(elem);
        var currentVal = {call: {}, std: {}};
        $.each(propsToBeChanged, (property, needCall)=>{
            needCall = needCall ? 'call' : 'std';
            currentVal[needCall][property] = new Boolean(); // is a minimal and unique value, its equivalent comparsion with each other will always return false
        });
        setInterval(function(){
            $.each(propsToBeChanged, (property, needCall)=>{
                try{
                    var currVal = needCall ? elem[property]() : elem[property];
                } catch (e){ // elem[property] is not a function anymore
                    var currVal = elem[property];
                    needCall = false;
                    propsToBeChanged[property] = false;
                }
                needCall = needCall ? 'call' : 'std';
                if (currVal !== currentVal[needCall][property]){
                    currentVal[needCall][property] = currVal;
                    func.apply(null, args);
                }
            });
        }, interval);
    }

去尝试一下:

var b = '2',
    a = {foo: 'bar', ext: ()=>{return b}};
changed(a, {
// prop name || do eval like a function?
    foo:        false,
    ext:        true
}, ()=>{console.log('changed')})

每次直接更改 b、a.foo 或 a.ext 时,它都会记录 'changed'

于 2017-06-12T08:22:33.310 回答
0

您可以根据屏幕大小更改文本或内容或属性: HTML:

<p class="change">Frequently Asked Questions (FAQ)</p>
<p class="change">Frequently Asked Questions </p>

Javascript:

<script>
const changeText = document.querySelector('.change');
function resize() {
  if((window.innerWidth<500)&&(changeText.textContent="Frequently Asked Questions (FAQ)")){
    changeText.textContent="FAQ";
  } else {
    changeText.textContent="Frequently Asked Questions (FAQ)";
  }
}
window.onresize = resize;
</script>
于 2019-01-16T05:57:12.740 回答
0

document.addEventListener('transitionend', function(e) {
  if ($(e.target).is("div")) {
    $("div").text("width: "+$("div").width());
  }
});
$("div").css({"width":"150px"});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="width: 100px;transition-delay: 0.000000001s;">width: 100</div>

于 2021-12-22T12:19:22.567 回答
-2

如果您只想调整 div 本身的大小,则需要以 css 样式指定。您需要添加溢出调整大小属性

下面是我的代码片段

#div1 {
        width: 90%;
        height: 350px;
        padding: 10px;
        border: 1px solid #aaaaaa;
        overflow: auto;
        resize: both;
    }

<div id="div1">

</div>
于 2019-07-18T13:08:49.100 回答