使用jQuery检测div的高度何时发生变化

Bob*_*ers 140 javascript jquery

我有一个div包含一些动态添加和删除的内容,所以它的高度经常变化.我也有一个div绝对定位在javascript的正下方,所以除非我能检测到div的高度何时改变,否则我无法重新定位它下方的div.

那么,我怎样才能检测到div的高度何时发生变化?我假设我需要使用一些jQuery事件,但我不确定要挂入哪一个.

Mar*_*idt 64

使用css-element-queries库中的resize传感器:

https://github.com/marcj/css-element-queries

new ResizeSensor(jQuery('#myElement'), function() {
    console.log('myelement has been resized');
});
Run Code Online (Sandbox Code Playgroud)

它使用基于事件的方法,不会浪费您的CPU时间.适用于所有浏览器.IE7 +.

  • 很好的解决方案,它使用一个不可见的新元素作为所需目标的叠加层,并利用叠加层上的"滚动"事件来触发更改. (5认同)
  • 这是唯一适用于所有情况的解决方案,包括内容和属性不会更改但尺寸更改时(例如:使用css的百分比尺寸) (2认同)
  • 最佳答案,需要更多的投票 (2认同)
  • 迄今为止的最佳解决方 (2认同)

Sel*_*gam 49

我曾经为attrchange监听器编写了一个插件,它基本上在属性更改时添加了一个监听器函数.即使我说它是一个插件,实际上它是一个简单的函数编写为jQuery插件..所以如果你想..剥离插件specfic代码并使用核心功能.

注意:此代码不使用轮询

看看这个简单的演示http://jsfiddle.net/aD49d/

$(function () {
    var prevHeight = $('#test').height();
    $('#test').attrchange({
        callback: function (e) {
            var curHeight = $(this).height();            
            if (prevHeight !== curHeight) {
               $('#logger').text('height changed from ' + prevHeight + ' to ' + curHeight);

                prevHeight = curHeight;
            }            
        }
    }).resizable();
});
Run Code Online (Sandbox Code Playgroud)

插件页面: http ://meetselva.github.io/attrchange/

缩小版:(1.68kb)

(function(e){function t(){var e=document.createElement("p");var t=false;if(e.addEventListener)e.addEventListener("DOMAttrModified",function(){t=true},false);else if(e.attachEvent)e.attachEvent("onDOMAttrModified",function(){t=true});else return false;e.setAttribute("id","target");return t}function n(t,n){if(t){var r=this.data("attr-old-value");if(n.attributeName.indexOf("style")>=0){if(!r["style"])r["style"]={};var i=n.attributeName.split(".");n.attributeName=i[0];n.oldValue=r["style"][i[1]];n.newValue=i[1]+":"+this.prop("style")[e.camelCase(i[1])];r["style"][i[1]]=n.newValue}else{n.oldValue=r[n.attributeName];n.newValue=this.attr(n.attributeName);r[n.attributeName]=n.newValue}this.data("attr-old-value",r)}}var r=window.MutationObserver||window.WebKitMutationObserver;e.fn.attrchange=function(i){var s={trackValues:false,callback:e.noop};if(typeof i==="function"){s.callback=i}else{e.extend(s,i)}if(s.trackValues){e(this).each(function(t,n){var r={};for(var i,t=0,s=n.attributes,o=s.length;t<o;t++){i=s.item(t);r[i.nodeName]=i.value}e(this).data("attr-old-value",r)})}if(r){var o={subtree:false,attributes:true,attributeOldValue:s.trackValues};var u=new r(function(t){t.forEach(function(t){var n=t.target;if(s.trackValues){t.newValue=e(n).attr(t.attributeName)}s.callback.call(n,t)})});return this.each(function(){u.observe(this,o)})}else if(t()){return this.on("DOMAttrModified",function(e){if(e.originalEvent)e=e.originalEvent;e.attributeName=e.attrName;e.oldValue=e.prevValue;s.callback.call(this,e)})}else if("onpropertychange"in document.body){return this.on("propertychange",function(t){t.attributeName=window.event.propertyName;n.call(e(this),s.trackValues,t);s.callback.call(this,t)})}return this}})(jQuery)
Run Code Online (Sandbox Code Playgroud)

  • 如果您手动调整div的大小,这解决了问题,这不能解决原来的问题吗?如果您动态添加内容,则无法检测到高度变化:http://jsfiddle.net/aD49d/25/ (25认同)
  • @JoeCoder当存在用户操作时,此交换代码依赖于浏览器触发的DOM事件.但是,该示例中的动态内容以编程方式包含在内,遗憾的是,它不会触发任何事件."轮询"似乎是另一种更容易的选择..其他选项可以在包含动态内容后手动触发. (4认同)

eye*_*ess 28

您可以使用DOMSubtreeModified事件

$(something).bind('DOMSubtreeModified' ...
Run Code Online (Sandbox Code Playgroud)

但即使尺寸没有变化,这也会触发,并且每当发生火灾时重新分配位置都会受到性能影响.根据我使用此方法的经验,检查尺寸是否已更改更便宜,因此您可以考虑将两者结合使用.

或者,如果您直接更改div(而不是以不可预测的方式通过用户输入更改div,例如,如果它是contentEditable),则只需在您执行此操作时触发自定义事件即可.

缺点:IE和Opera没有实现此事件.

  • DomSubtreeModified得到了诽谤 (14认同)
  • IE和Opera不会实现此事件:http://www.quirksmode.org/dom/events/index.html (12认同)
  • 真正.注意补充说. (2认同)
  • 这样做的现代方法是使用MutationObserver:https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver (2认同)

Kyl*_*yle 20

这就是我最近处理这个问题的方法:

$('#your-resizing-div').bind('getheight', function() {
    $('#your-resizing-div').height();
});

function your_function_to_load_content() {
    /*whatever your thing does*/
    $('#your-resizing-div').trigger('getheight');
}
Run Code Online (Sandbox Code Playgroud)

我知道我已经晚了几年,只是觉得我的答案可能会帮助将来的某些人,而不必下载任何插件.


EFe*_*des 16

你可以使用MutationObserver课程.

MutationObserver为开发人员提供了一种对DOM中的更改做出反应的方法.它被设计为DOM3 Events规范中定义的Mutation Events的替代品.

示例(来源)

// select the target node
var target = document.querySelector('#some-id');

// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });    
});

// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };

// pass in the target node, as well as the observer options
observer.observe(target, config);

// later, you can stop observing
observer.disconnect();
Run Code Online (Sandbox Code Playgroud)

  • 这只适用于IE11 + http://caniuse.com/#feat=mutationobserver (2认同)

Val*_*Val 9

有一个jQuery插件可以很好地处理这个问题

http://www.jqui.net/jquery-projects/jquery-mutate-official/

这里有一个演示,它有不同的场景,关于高度何时改变,如果你调整红色边框div.

http://www.jqui.net/demo/mutate/


apa*_*aul 7

响应user007:

如果元素的高度因使用的项目附加而.append()发生变化,则不需要检测高度的变化.只需将第二个元素的重新定位添加到您将新内容附加到第一个元素的同一个函数中.

如:

工作实例

$('.class1').click(function () {
    $('.class1').append("<div class='newClass'><h1>This is some content</h1></div>");
    $('.class2').css('top', $('.class1').offset().top + $('.class1').outerHeight());
});
Run Code Online (Sandbox Code Playgroud)