我有一个 div,其中包含一些动态添加和删除的内容,因此它的高度经常变化。我还有一个 div,它绝对位于 javascript 正下方,因此除非我可以检测到 div 的高度何时发生变化,否则我无法将 div 重新定位在其下方。
那么,如何检测该 div 的高度何时发生变化?我假设有一些我需要使用的 jQuery 事件,但我不确定要连接到哪个事件。
我有一个 div,其中包含一些动态添加和删除的内容,因此它的高度经常变化。我还有一个 div,它绝对位于 javascript 正下方,因此除非我可以检测到 div 的高度何时发生变化,否则我无法将 div 重新定位在其下方。
那么,如何检测该 div 的高度何时发生变化?我假设有一些我需要使用的 jQuery 事件,但我不确定要连接到哪个事件。
使用 css-element-queries 库中的调整大小传感器:
https://github.com/marcj/css-element-queries
new ResizeSensor(jQuery('#myElement'), function() {
console.log('myelement has been resized');
});
它使用基于事件的方法,不会浪费您的 CPU 时间。适用于所有浏览器,包括。IE7+。
我曾经为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();
});
插件页面: 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(而不是由用户输入以不可预测的方式更改 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 中的变化做出react的方法。它旨在替代 DOM3 事件规范中定义的突变事件。
示例(来源)
// 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();