Is there any way to set a jQuery event when some (any one) element changes its own height?
I really can't find out how I can fire thi.s
Like:
$('body *').onHeightChange(function(){
//do somenthing
});
Is there any way to set a jQuery event when some (any one) element changes its own height?
I really can't find out how I can fire thi.s
Like:
$('body *').onHeightChange(function(){
//do somenthing
});
Share
Improve this question
edited Jul 18, 2022 at 18:24
Brian Tompsett - 汤莱恩
5,89372 gold badges61 silver badges133 bronze badges
asked Dec 18, 2012 at 15:32
Filippo orettiFilippo oretti
49.8k96 gold badges229 silver badges351 bronze badges
8
- That would be very intense on the proc. Is there specific elements you want monitored? If so, it's not too hard. You just create a timer and watch for the height to be different. – SpYk3HH Commented Dec 18, 2012 at 15:35
- Be more specific, what element(s) you doing this on? – Alex Gill Commented Dec 18, 2012 at 15:35
- Possible duplicate: stackoverflow./questions/172821/… – tungd Commented Dec 18, 2012 at 15:35
- nope i don't have specific element cause of it can be a div as a span, random – Filippo oretti Commented Dec 18, 2012 at 15:36
-
1
Sorry if I confused anybody, my code snippet will only work with the plugin benalman./projects/jquery-resize-plugin. It's meant to help when you don't have a specific element (as in the case of the author). The plugin use timer internally and still work when the element is changed by anything rather than just some specific jQuery functions. @RobinvanBaalen: It does, but not very much as we do not really watch every elements, but wait for the event bubble to the
body
. You can replacebody
with the outer most container of the elements that might change. – tungd Commented Dec 18, 2012 at 17:20
4 Answers
Reset to default 9Whenever you do something that changes the height of the element, trigger an event.
$("#somelement").slideDown().trigger("heightchange");
Now you can bind to that:
$("body").on("heightchange",function(e){
var $el = $(e.target); // the element that has a new height.
});
You could even monkeypatch a lot of the jQuery methods that can change the height and have them test the height before and after using the method and trigger the event accordingly. Below is an untested example
var topatch = ["slideup","slidedown","height","width","attr","css","animate"];
$.each(topatch,function(i,method){
var oldfn = $.fn[method];
$.fn[method] = function(){
return this.each(function(){
var $this = $(this), currHeight = $this.css("height"),
result = oldfn.apply($this,arguments);
// check for promise object to deal with animations
if ( $.isFunction(result.promise) ) {
result.promise().done(function(){
if ( currHeight != $this.css("height") ) {
$this.trigger("heightchange");
}
});
return;
}
if ( currHeight != $this.css("height") ) {
$this.trigger("heightchange");
}
});
};
});
I think the only event you can use is the 'DOMSubtreeModified'.
you should use jQuery mutate
which has handlers for width
, height
and more
http://www.jqui/jquery-projects/jquery-mutate-official/
I thought about it, and I know you already have your answer, the trigger thing is great idea, but if you really want a simple plugin on all possible elements, you could use what I made below. It's just a simple jQuery plugin that makes use of a timer and a callback function for when a height has changed. See the fiddle for example use. Warning Too many elements on the page could cause issues.
jsFiddle
Dirty Plugin
(function($) {
if (!$.onHeightChange) {
$.extend({
onHeightChange: function(callBack) {
if (typeof callBack == "string") {
switch (callBack.toLowerCase()) {
case "play":
$.onHeightChange.init();
break;
case "stop":
try { clearInterval($.onHeightChange.timer); } catch(err) { };
break;
}
}
else if (typeof callBack == "function" || callBack == undefined)
{
$.onHeightChange.callback = callBack;
$.onHeightChange.init(callBack);
}
}
});
$.onHeightChange.timer;
$.onHeightChange.init = function(callBack) {
$("body,body *").each(function(i) {
$(this).data("onHeightChange", { height: $(this).height(), outer: $(this).outerHeight() });
});
try { clearInterval($.onHeightChange.timer); } catch(err) { };
$.onHeightChange.timer = setInterval(function() {
$("body, body *").each(function(i) {
if ($(this).data("onHeightChange").height != $(this).height()) {
$(this).data("onHeightChange", { height: $(this).height(), outer: $(this).outerHeight() });
if ($.onHeightChange['callback']) {
if (typeof $.onHeightChange.callback == "function") return $.onHeightChange.callback .call(this, $(this), $(this).height(), $(this).outerHeight());
}
}
});
}, 100);
};
}
})(jQuery);
Example Use
$.onHeightChange(function(ele, height, outer) {
console.log(ele, height, outer);
});
/*---------------------------------------------*/
$.onHeightChange("stop");
$.onHeightChange("play");