Basically, I am wondering if there is a way to automatically run a function when an element becomes hidden or visible, not on a user click but automatically in another script.
I don't want this to just run one time, because the elements (such as a slider) constantly change from visible to hidden.
Would this be something that jQuery can do with bind? Such as binding the element's visibility to a function (I don't know how to write this)
If you need me to elaborate more on what I'm trying to do, let me know. Thanks
Pseudocode:
$('#element').bind('display:none', function);
function(){
//do something when element is display:none
}
$('#element').bind('display:block', function2);
function2(){
//do opposite of function
}
This question is related to
javascript
jquery
html
css
A catch-all jQuery custom event based on an extension of it's core methods like it was proposed by different people in this thread:
(function() {
var ev = new $.Event('event.css.jquery'),
css = $.fn.css,
show = $.fn.show,
hide = $.fn.hide;
// extends css()
$.fn.css = function() {
css.apply(this, arguments);
$(this).trigger(ev);
};
// extends show()
$.fn.show = function() {
show.apply(this, arguments);
$(this).trigger(ev);
};
// extends hide()
$.fn.hide = function() {
hide.apply(this, arguments);
$(this).trigger(ev);
};
})();
An external library then, uses sth like $('selector').css('property', value)
.
As we don't want to alter the library's code but we DO want to extend it's behavior we do sth like:
$('#element').on('event.css.jquery', function(e) {
// ...more code here...
});
Example: user clicks on a panel that is built by a library. The library shows/hides elements based on user interaction. We want to add a sensor that shows that sth has been hidden/shown because of that interaction and should be called after the library's function.
Another example: jsfiddle.
I like plugin https://github.com/hazzik/livequery It works without timers!
Simple usage
$('.some:visible').livequery( function(){ ... } );
But you need to fix a mistake. Replace line
$jQlq.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove', 'html', 'prop', 'removeProp');
to
$jQlq.registerPlugin('show', 'append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove', 'html', 'prop', 'removeProp');
(function() {
var ev = new $.Event('display'),
orig = $.fn.css;
$.fn.css = function() {
orig.apply(this, arguments);
$(this).trigger(ev);
}
})();
$('#element').bind('display', function(e) {
alert("display has changed to :" + $(this).attr('style') );
});
$('#element').css("display", "none")// i change the style in this line !!
$('#element').css("display", "block")// i change the style in this line !!
http://fiddle.jshell.net/prollygeek/gM8J2/3/
changes will be alerted.
I just Improved ProllyGeek`s answer
Someone may find it useful.
you can access displayChanged(event, state)
event when .show()
, .hide()
or .toggle()
is called on element
(function() {
var eventDisplay = new $.Event('displayChanged'),
origShow = $.fn.show,
origHide = $.fn.hide;
//
$.fn.show = function() {
origShow.apply(this, arguments);
$(this).trigger(eventDisplay,['show']);
};
//
$.fn.hide = function() {
origHide.apply(this, arguments);
$(this).trigger(eventDisplay,['hide']);
};
//
})();
$('#header').on('displayChanged', function(e,state) {
console.log(state);
});
$('#header').toggle(); // .show() .hide() supported
Tried this on firefox, works http://jsfiddle.net/Tm26Q/1/
$(function(){
/** Just to mimic a blinking box on the page**/
setInterval(function(){$("div#box").hide();},2001);
setInterval(function(){$("div#box").show();},1000);
/**/
});
$("div#box").on("DOMAttrModified",
function(){if($(this).is(":visible"))console.log("visible");});
UPDATE
Currently the Mutation Events (like
DOMAttrModified
used in the solution) are replaced by MutationObserver, You can use that to detect DOM node changes like in the above case.
Source: Stackoverflow.com