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
});
Whenever 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
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.
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");