使用jQuery检测div的高度发生什么变化

我有一个包含一些内容的dynamic添加和删除,所以其高度经常变化。 我也有一个绝对定位在JavaScript下面的div,所以除非我能检测到div的高度发生变化,否则我不能重新定位它下面的div。

那么,如何检测div的高度发生了什么变化呢? 我假设有一些我需要使用的jQuery事件,但是我不确定应该使用哪一个。

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

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

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

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

我有时候为attrchange监听器写了一个插件,它基本上在属性更改上添加了一个监听器函数。 即使我把它作为一个插件,实际上它是一个简单的函数写成一个jQuery插件..所以如果你想剥离插件specfic代码和使用核心function。

注意:此代码不使用轮询

看看这个简单的演示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(); }); 

插件页面: 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) 

您可以使用DOMSubtreeModified事件

 $(something).bind('DOMSubtreeModified' ... 

但即使尺寸没有变化,这种情况也会发生,每当发生火灾时重新分配位置都会导致性能下降。 根据我使用这种方法的经验,检查尺寸是否已经变化了,所以你可能会考虑把这两者结合起来。

或者,如果直接改变div(而不是以不可预知的方式改变用户input的div,比如contentEditable),那么只要你这样做就可以简单地触发一个自定义事件。

缺点:IE和Opera不执行这个事件。

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

 $('#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'); } 

我知道我晚了几年,只是觉得我的答案可能会帮助一些人在未来,而不必下载任何插件。

你可以使用MutationObserver类。

MutationObserver为开发人员提供了对DOM中的更改作出反应的方法。 它被devise为DOM3 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(); 

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

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

这里是一个演示与不同的情况下,当高度变化,如果你调整红色边界的div。

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

响应用户007:

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

如:

工作示例

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

你可以做一个简单的setInterval。

 function someJsClass() { var _resizeInterval = null; var _lastHeight = 0; var _lastWidth = 0; this.Initialize = function(){ var _resizeInterval = setInterval(_resizeIntervalTick, 200); }; this.Stop = function(){ if(_resizeInterval != null) clearInterval(_resizeInterval); }; var _resizeIntervalTick = function () { if ($(yourDiv).width() != _lastWidth || $(yourDiv).height() != _lastHeight) { _lastWidth = $(contentBox).width(); _lastHeight = $(contentBox).height(); DoWhatYouWantWhenTheSizeChange(); } }; } var class = new someJsClass(); class.Initialize(); 

你可以使用这个,但它只支持Firefox和Chrome。

 $(element).bind('DOMSubtreeModified', function () { var $this = this; var updateHeight = function () { var Height = $($this).height(); console.log(Height); }; setTimeout(updateHeight, 2000); });