javascript - tiene - Detectando cuando cambia la altura de un div usando jQuery
quitar propiedades con jquery (10)
Tengo un div que contiene un contenido que se agrega y quita dinámicamente, por lo que su altura cambia con frecuencia. También tengo un div que está absolutamente posicionado directamente debajo con javascript, así que a menos que pueda detectar cuándo cambia la altura del div, no puedo reposicionar el div debajo de él.
Entonces, ¿cómo puedo detectar cuándo cambia la altura de ese div? Supongo que hay algún evento de jQuery que necesito usar, pero no estoy seguro de cuál enganchar.
Así es como manejé este problema recientemente:
$(''#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'');
}
Sé que llegué unos años tarde a la fiesta, solo creo que mi respuesta puede ayudar a algunas personas en el futuro, sin tener que descargar ningún complemento.
Bastante básico pero funciona:
function dynamicHeight() {
var height = jQuery('''').height();
jQuery(''.edito-wrapper'').css(''height'', editoHeight);
}
editoHeightSize();
jQuery(window).resize(function () {
editoHeightSize();
});
Escribí un plugin en algún momento atrás para attrchange oyente que básicamente agrega una función de oyente en el cambio de atributo. Aunque lo digo como un plugin, en realidad es una función simple escrita como un plugin jQuery ... así que si quieres ... quita el código specfic del plugin y usa las funciones principales.
Nota: Este código no usa encuestas
echa un vistazo a esta demostración simple 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();
});
Página de complemento: attrchange
Versión Minificada: (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)
Hay un complemento jQuery que puede manejar esto muy bien
http://www.jqui.net/jquery-projects/jquery-mutate-official/
Aquí hay una demostración de ella con diferentes escenarios en cuanto a cuándo cambia la altura, si cambia el tamaño de la div bordeada de rojo.
Puede usar el evento DOMSubtreeModified
$(something).bind(''DOMSubtreeModified'' ...
Pero esto disparará incluso si las dimensiones no cambian, y la reasignación de la posición cada vez que se dispara puede tener un impacto en el rendimiento. En mi experiencia con este método, comprobar si las dimensiones han cambiado es menos costoso y, por lo tanto, podría considerar combinar los dos.
O si está alterando directamente el div (en lugar de que el div sea alterado por la entrada del usuario de maneras impredecibles, como si fuera contentEditable), puede simplemente iniciar un evento personalizado cada vez que lo haga.
Desventaja: IE y Opera no implementan este evento.
Puede usar la clase developer.mozilla.org/en-US/docs/Web/API/MutationObserver .
MutationObserver
proporciona a los desarrolladores una forma de reaccionar a los cambios en un DOM. Está diseñado como un reemplazo para los eventos de mutación definidos en la especificación de eventos DOM3.
Ejemplo ( source )
// 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();
Puedes hacer un setInterval simple.
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();
EDITAR:
Este es un ejemplo con una clase. Pero puedes hacer algo más fácil.
Puedes usar esto, pero solo es compatible con Firefox y Chrome.
$(element).bind(''DOMSubtreeModified'', function () {
var $this = this;
var updateHeight = function () {
var Height = $($this).height();
console.log(Height);
};
setTimeout(updateHeight, 2000);
});
Utilice un sensor de cambio de tamaño de la biblioteca css-element-queries:
https://github.com/marcj/css-element-queries
new ResizeSensor(jQuery(''#myElement''), function() {
console.log(''myelement has been resized'');
});
Utiliza un enfoque basado en eventos y no pierde tu tiempo de CPU. Funciona en todos los navegadores incl. IE7 +.
En respuesta a user007:
Si la altura de su elemento está cambiando debido a elementos que se anexan utilizando .append()
no debería necesitar detectar el cambio de altura. Simplemente agregue la reposición de su segundo elemento en la misma función donde está agregando el nuevo contenido a su primer elemento.
Como en:
$(''.class1'').click(function () {
$(''.class1'').append("<div class=''newClass''><h1>This is some content</h1></div>");
$(''.class2'').css(''top'', $(''.class1'').offset().top + $(''.class1'').outerHeight());
});