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

我有一个 div,它包含一些动态添加和删除的内容,所以它的高度经常变化。我还有一个 div,它绝对位于 javascript 的正下方,所以除非我可以检测到 div 的高度发生了变化,否则我不能将 div 重新定位到它的下方。

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

209149 次浏览

可以使用 DOMSubtreeAmendment 事件

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

但是即使尺寸没有改变,这也会发射,并且在发射时重新分配位置会对性能造成影响。根据我使用这种方法的经验,检查维度是否已经更改的开销较小,因此可以考虑将两者结合起来。

或者,如果直接修改 div (而不是通过用户输入以不可预知的方式修改 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');
}

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

回应 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());
});

我曾经为 译自: 美国《科学》杂志网站(http://meetselva.github.io/attrchange/)侦听器编写过一个插件,基本上就是在属性更改上添加一个侦听器函数。尽管我说它是一个插件,但实际上它是一个简单的函数,用 jQuery 插件编写。.所以如果你想的话。.去掉插件的特定代码,使用核心函数。

注意: 此代码不使用轮询

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

插件页面: < a href = “ http://meetselva.github.io/attrchange/”> http://meetselva.github.io/attrchange/

缩减版: (1.68 kb)

(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)

使用 css-element-query 库中的调整大小传感器:

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

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

它使用了一种基于事件的方法,并且不会浪费你的 CPU 时间。

您可以使用 MutationObserver类。

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

您可以创建一个简单的 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);
});

非常基本,但很管用:

function dynamicHeight() {
var height = jQuery('').height();
jQuery('.edito-wrapper').css('height', editoHeight);
}
editoHeightSize();


jQuery(window).resize(function () {
editoHeightSize();
});

现在您还可以使用 Web API ResizeObserver

举个简单的例子:

const myElement = document.querySelector('#myElement');


const resizeObserver = new ResizeObserver(() => {
console.log('size of myElement changed');
});


resizeObserver.observe(myElement);