I apologize if this was answered previously, I couldn't find it using the search.
I have to tag 4 elements to fire off an event when they are unhidden ("display: none" is removed). I think a mutationObserver is the right way to go, but am having trouble filtering to just the event I need.
Anyone have experience doing this?
Edit: Unfortunately, we do not have access to the script actually unhiding the elements. They are owned and protected by another team. The only thing we can key on is when the element is unhidden.
I was trying to figure out how to edit this for my needs.
// Blocker is the element that has a changing display value
var blocker = document.querySelector( '#blocker' );
// Trigger changes the display value of blocker
var trigger = document.querySelector( '#trigger' );
// Our mutation observer, which we attach to blocker later
var observer = new MutationObserver( function( mutations ){
mutations.forEach( function( mutation ){
// Was it the style attribute that changed? (Maybe a classname or other attribute change could do this too? You might want to remove the attribute condition) Is display set to 'none'?
if( mutation.attributeName === 'style' && window.getComputedStyle( blocker ).getPropertyValue( 'display' ) !== 'none'
){
alert( '#blocker\'s style just changed, and its display value is no longer \'none\'' );
}
} );
} );
// Attach the mutation observer to blocker, and only when attribute values change
observer.observe( blocker, { attributes: true } );
// Make trigger change the style attribute of blocker
trigger.addEventListener( 'click', function(){
blocker.removeAttribute( 'style' );
}, false );
I apologize if this was answered previously, I couldn't find it using the search.
I have to tag 4 elements to fire off an event when they are unhidden ("display: none" is removed). I think a mutationObserver is the right way to go, but am having trouble filtering to just the event I need.
Anyone have experience doing this?
Edit: Unfortunately, we do not have access to the script actually unhiding the elements. They are owned and protected by another team. The only thing we can key on is when the element is unhidden.
I was trying to figure out how to edit this for my needs.
// Blocker is the element that has a changing display value
var blocker = document.querySelector( '#blocker' );
// Trigger changes the display value of blocker
var trigger = document.querySelector( '#trigger' );
// Our mutation observer, which we attach to blocker later
var observer = new MutationObserver( function( mutations ){
mutations.forEach( function( mutation ){
// Was it the style attribute that changed? (Maybe a classname or other attribute change could do this too? You might want to remove the attribute condition) Is display set to 'none'?
if( mutation.attributeName === 'style' && window.getComputedStyle( blocker ).getPropertyValue( 'display' ) !== 'none'
){
alert( '#blocker\'s style just changed, and its display value is no longer \'none\'' );
}
} );
} );
// Attach the mutation observer to blocker, and only when attribute values change
observer.observe( blocker, { attributes: true } );
// Make trigger change the style attribute of blocker
trigger.addEventListener( 'click', function(){
blocker.removeAttribute( 'style' );
}, false );
Share
Improve this question
edited Nov 25, 2024 at 10:19
DarkBee
15.6k8 gold badges70 silver badges115 bronze badges
asked May 11, 2016 at 16:17
Nathan PoorbaughNathan Poorbaugh
531 gold badge1 silver badge4 bronze badges
2
|
3 Answers
Reset to default 12The code below works if display:none
is set via the style attribute. If you also need to handle the case where it's shown/hidden via toggling a class, then use the ResizeObserver
approach as shown in BenVida's answer.
var blocker = document.querySelector('#blocker');
var previousValue = blocker.style.display;
var observer = new MutationObserver( function(mutations){
mutations.forEach( function(mutation) {
if (mutation.attributeName !== 'style') return;
var currentValue = mutation.target.style.display;
if (currentValue !== previousValue) {
if (previousValue === "none" && currentValue !== "none") {
console.log("display none has just been removed!");
}
previousValue = mutation.target.style.display;
}
});
});
observer.observe(blocker, { attributes: true });
Basically we get the default value set in the style attribute (if there is any) - this is stored in previousValue
; Then we leave the code, but we make some differences in the loop. Firstly we check whether the style was changed in the target. Then we get the current display value in the target's style attribute. Next step is to compare those values. If previousValue was "none" and now it's something else, this means the display: none was unset. However you must note that it listens only for this specific change. If you don't need to listen for "none" then you may omit it.
You can use it in your code - I didn't write your entire code on purpose, so feel free to add your event listener on target.
There's another way I found that works reliably to trigger events when an element is hidden by display:none
or becomes visible.
This is based on the ResizeObserver API which should work in all modern browsers (https://developer.mozilla.org/en-US/docs/Web/API/Resize_Observer_API)
When an element has css rule display:none
applied to it then all its dimensions will be zero. So in order to detect becoming visible we just need to watch an element which has non-zero dimensions when visible.
const block=document.querySelector("#the-block")
const resizewatcher=new ResizeObserver(entries => {
for (const entry of entries){
console.log("Element",entry.target,
(entry.contentRect.width == 0) ?
"is now hidden" :
"is now visible"
)
}
})
resizewatcher.observe(block)
Unfortunately, I'm unsure of how you're "removing" display: none
, however, if you're, by some chance, using jQuery's $.show
function, then you could specify a "callback" function, which would be called upon once the show "animation" has finished.
Here's an example:
$(".myElement").show(400, function() {
// Do something...
});
Again, I'm unsure of how you're removing display: none
, so this may not be helpful at all.
display: none
? – David Thomas Commented May 11, 2016 at 16:21