Rilevare quando l’altezza di un div cambia usando jQuery

Ho un div che contiene del contenuto che viene aggiunto e rimosso dynamicmente, quindi la sua altezza sta cambiando spesso. Ho anche un div che è assolutamente posizionato direttamente sotto con javascript, quindi a meno che non riesca a rilevare quando l’altezza del div cambia, non riesco a riposizionare il div al di sotto di esso.

Quindi, come posso rilevare quando cambia l’altezza di quel div? Presumo che ci sia qualche evento jQuery che ho bisogno di usare, ma non sono sicuro su quale si possa colbind.

Utilizzare un sensore di ridimensionamento dalla libreria css-element-query:

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

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

Utilizza un approccio basato sugli eventi e non spreca il tempo della CPU. Funziona su tutti i browser incl. IE7 +.

Ho scritto un plugin qualche volta indietro per ascoltatore attrchange che fondamentalmente aggiunge una funzione listener al cambio di attributo. Anche se lo dico come un plugin, in realtà è una semplice funzione scritta come un plugin jQuery .. quindi se vuoi .. elimina il codice specfic del plugin e usa le funzioni principali.

Nota: questo codice non utilizza il polling

guarda questa semplice demo 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(); }); 

Pagina del plugin: http://meetselva.github.io/attrchange/

Versione minificata: (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 

È ansible utilizzare l’evento DOMSubtreeModified

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

Ma questo sparerà anche se le dimensioni non cambiano, e la riassegnazione della posizione ogni volta che spara può prendere un colpo di prestazioni. Nella mia esperienza con questo metodo, controllare se le dimensioni sono cambiate è meno costoso e quindi potresti prendere in considerazione la combinazione dei due.

Oppure, se si modifica direttamente il div (piuttosto che il div viene modificato dall’input dell’utente in modi imprevedibili, come se fosse contentEditable), è ansible semplicemente triggersre un evento personalizzato ogni volta che lo si fa.

Lato negativo: IE e Opera non implementano questo evento.

Questo è il modo in cui ho gestito questo problema di recente:

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

So che sono in ritardo di qualche anno, basti pensare che la mia risposta potrebbe aiutare alcune persone in futuro, senza dover scaricare alcun plug-in.

Puoi usare la class MutationObserver .

MutationObserver offre agli sviluppatori un modo per reactjs ai cambiamenti in un DOM. È progettato come sostituto degli eventi di mutazione definiti nella specifica degli eventi di DOM3.

Esempio ( fonte )

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

C’è un plugin jQuery che può gestire questo molto bene

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

qui è una demo di esso con diversi scenari su quando cambiare l’altezza, se si ridimensiona il div rosso bordato.

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

In risposta a user007:

Se l’altezza del tuo elemento sta cambiando a causa di elementi che vengono aggiunti ad esso utilizzando .append() non è necessario rilevare il cambiamento di altezza. Aggiungi semplicemente la riposizionamento del tuo secondo elemento nella stessa funzione in cui aggiungi i nuovi contenuti al tuo primo elemento.

Come in:

Esempio di lavoro

 $('.class1').click(function () { $('.class1').append("

This is some content

"); $('.class2').css('top', $('.class1').offset().top + $('.class1').outerHeight()); });

Puoi creare un semplice 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(); 

Puoi usare questo, ma supporta solo Firefox e Chrome.

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

Abbastanza semplice ma funziona:

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