Site logo

Archived topic

insert image on top of product thumbnail if product is sold out

26 replies · Started by nik9 on December 14, 2020

Viewing posts 16–27 of 27

Ah, I posted the wrong code. My bad.

Here's the one I was supposed to give.

<script>

function coming_soon_toggle(){
    var wcgallery = document.querySelector('figure.woocommerce-product-gallery__wrapper'); //woocommerce photo wrapper
    var comingsoon = wcgallery.querySelector('div.sold_out_loop_wrapper'); // coming soon wrapper
    comingsoon.style.transition = "opacity 0.1s ease-in-out"; // Added transition

    wcgallery.addEventListener("mouseout", function( event ) {   //hover out
        comingsoon.style.display = "block"; // puts it back on the DOM
        comingsoon.style.opacity = '1'; //display it when not hovering
    }, false);

    wcgallery.addEventListener("mouseover", function( event ) {   //while hovering
        comingsoon.style.opacity = "0"; //remove from display on hover
        setTimeout(function(){ comingsoon.style.display = "none"; }, 1000); //hides it from DOM
    }, false);

}
window.addEventListener('DOMContentLoaded', function(){
    coming_soon_toggle(); //run the script after loading all elements
});

</script>

I guess this happens because the display of the coming soon image is not “none” and still there, isn’t it?

That's correct. That's actually the issue why the CSS approach wasn't working. We needed the JS to make use of setTimeout() function so it adds display:none; exactly after finishing the animation so there's no DOM that blocks with WooCommerce image's eventlisteners.

Hi Elvin,

Hmm.. Now the Zoom is working sometime and sometime not.. and after hover out, the coming soon image is disappears after 1s.

The first js works the best currently. There we only have not a very smooth transition. Is there a quick way to give the comingsoon.style.display = "none"; //remove from display on hover maybe a transition like transition: opacity 1s ease-out; or something?

<script>

function coming_soon_toggle(){
    var wcgallery = document.querySelector('figure.woocommerce-product-gallery__wrapper'); //woocommerce photo wrapper
    var comingsoon = wcgallery.querySelector('div.sold_out_loop_wrapper'); // coming soon wrapper

    wcgallery.addEventListener("mouseout", function( event ) {   //hover out
        comingsoon.style.display = 'block'; //display it when not hovering
    }, false);

    wcgallery.addEventListener("mouseover", function( event ) {   //while hovering
        comingsoon.style.display = "none"; //remove from display on hover
    }, false);

}
window.addEventListener('DOMContentLoaded', function(){
    coming_soon_toggle(); //run the script after loading all elements
});

</script>

The first js works the best currently. There we only have not a very smooth transition. Is there a quick way to give the comingsoon.style.display = "none"; //remove from display on hover maybe a transition like transition: opacity 1s ease-out; or something?

This is precisely why it may be better to get a plugin for this. Developing this requires some thought on how to add in more conditions to make 2 display none and transition work well together.

You can try modifying the addeventlistener part of the script into this:

    wcgallery.addEventListener("mouseout", function( event ) {   //hover out
        comingsoon.style.opacity = '1'; //display it when not hovering
        if( comingsoon.style.opacity === '1'){
            comingsoon.style.display = "block"; // puts it back on the DOM
        }
    }, false);

    wcgallery.addEventListener("mouseover", function( event ) {   //while hovering
        comingsoon.style.opacity = '0'; //remove on hover
        if( comingsoon.style.opacity === '0'){
            comingsoon.style.display = "none"; // remove from DOM
        }
    }, false);

But I can't really be sure if this will work. Perhaps it needs a writeup to increment opacity from 0 to 1 and then fire display:none/block but that needs a longer code writeup and a few testing to do.

To remind: As previously mentioned, this is a site customization of a third party plugin (WooCommerce) which is outside of our scope.

Hi Elvin,

I see no problem. Thanks for the script. Its does not work but I go with the first one. :)

Cheers & many thanks
Nik

Elvin, Let me ask a last question. :)

What is the best way to adjust the script in order that is checks for a second class div.on_sale_loop_wrapper_single instead only one. Currently I just add a script twice and just changed the class here var comingsoon = wcgallery.querySelector('div.on_sale_loop_wrapper_single');

I guess it would be better not to add for each class check a whole script. :)

This is the script:

<script>

function coming_soon_toggle(){
    var wcgallery = document.querySelector('figure.woocommerce-product-gallery__wrapper'); //woocommerce photo wrapper
    var comingsoon = wcgallery.querySelector('div.on_sale_loop_wrapper_single'); // coming soon wrapper

    wcgallery.addEventListener("mouseout", function( event ) {   //hover out
        comingsoon.style.display = 'block'; //display it when not hovering
    }, false);

    wcgallery.addEventListener("mouseover", function( event ) {   //while hovering
        comingsoon.style.display = "none"; //remove from display on hover
    }, false);

}
window.addEventListener('DOMContentLoaded', function(){
    coming_soon_toggle(); //run the script after loading all elements
});

</script>

Cheers

What is the best way to adjust the script in order that is checks for a second class div.on_sale_loop_wrapper_single instead only one. Currently I just add a script twice and just changed the class here var comingsoon = wcgallery.querySelector('div.on_sale_loop_wrapper_single');

I guess it would be better not to add for each class check a whole script. 🙂

You can use the same function and just add in your extra eventlistener if its for a different one.

But if you're using the same event listener to affect extra classes, you can just add in more changes within its block functions.

But to answer the question: You can check w/ if condition what's existing first before assigning an eventlistener. You'll have to loop check the gallery's child for any specified classes and then assign the listener if found.

Example:

var wcgallery_children = wcgallery.querySelectorAll('*'); //selects all descendants of gallery

for(i=0; i.wcgallery_children.length;i++){ //looping through the descendants
        if( wcgallery_children[i].classList.contains('on_sale_loop_wrapper_single') ){ 
            //if class specified in contains() is found, do addEventlistener here.
            /
        } if( wcgallery_children[i].classList.contains('on_sale_loop_wrapper') ){ 
            //if class specified in contains() is found, do addEventlistener here.

        } else { return } //do nothing
}

This way, you'll only need one loop and just add in more if conditions for each class you want to do specific instructions with.

Hello Elvin

I trying this... But I guess this is wrong.
Currently we have 3 classes to add

div.sold_out_loop_wrapper_single
div.badge_loop_wrapper_single
div.special_loop_wrapper_single

<script>

function coming_soon_toggle2(){
    var wcgallery = document.querySelector('figure.woocommerce-product-gallery__wrapper'); //woocommerce photo wrapper
   		var wcgallery_children = wcgallery.querySelectorAll('div.badge_loop_wrapper_single','div.sold_out_loop_wrapper'); //selects all descendants of gallery

for(i=0; i.wcgallery_children.length;i++){ //looping through the descendants
        if( wcgallery_children.classList.contains() ){ 
            //if class specified in contains() is found, do addEventlistener here.
                      
					    wcgallery.addEventListener("mouseout", function( event ) {   //hover out
        comingsoon.style.display = 'block'; //display it when not hovering
    }, false);

    wcgallery.addEventListener("mouseover", function( event ) {   //while hovering
        comingsoon.style.display = "none"; //remove from display on hover
    }, false);
					

        } else { return } //do nothing
}

window.addEventListener('DOMContentLoaded', function(){
    coming_soon_toggle2(); //run the script after loading all elements
});

</script>

To clarify: These 3 new classes will have the same effect as comingsoon class? meaning it will use the same element (gallery) to use as hover trigger?

Let us know.

Yes, all of them would have the same effects.

Try this:

<script>

function coming_soon_toggle(){
    var wcgallery = document.querySelector('figure.woocommerce-product-gallery__wrapper');
    var wcgallery_children = wcgallery.querySelectorAll('*'); //selects all descendants of gallery
    var soldout;
    var badge;
    var special;

    for(i=0; i.wcgallery_children.length;i++){ //looping through the descendants
        if( wcgallery_children.classList.contains('sold_out_loop_wrapper_single') ){ 
            var soldout = wcgallery.querySelector('div.sold_out_loop_wrapper');
        } if( wcgallery_children.classList.contains('badge_loop_wrapper_single') ){ 
            var badge = wcgallery.querySelector('div.sold_out_loop_wrapper');
        } if( wcgallery_children.classList.contains('special_loop_wrapper_single') ){ 
            var special = wcgallery.querySelector('div.sold_out_loop_wrapper');
        } else { return } //do nothing
    }

    wcgallery.addEventListener("mouseout", function( event ) {   
        if( null != soldout ){ 
            soldout.style.display = "block";
        } if( null != badge ){ 
            badge.style.display = "block";
        } if( null != special ){ 
            special.style.display = "block";
        } else { return } //do nothing
    }, false);

    wcgallery.addEventListener("mouseover", function( event ) {   
        if( null != soldout ){ 
            soldout.style.display = "none";
        } if( null != badge ){ 
            badge.style.display = "none";
        } if( null != special ){ 
            special.style.display = "none";
        } else { return } //do nothing
    }, false);
}
window.addEventListener('DOMContentLoaded', function(){
    coming_soon_toggle();
});

</script>

I've significantly re-written the code to check for what is existing.

Not sure if it will work though. The code is getting a bit more complex and its hard to tell especially when I can't test it out completely on your setup.

Here's another way of doing it.

<script>

function coming_soon_toggle(){
    var wcgallery = document.querySelector('figure.woocommerce-product-gallery__wrapper');
    var wcgallery_children = wcgallery.querySelectorAll('*'); //selects all descendants of gallery
    var soldout;
    var badge;
    var special;

    for(i=0; i.wcgallery_children.length;i++){ //looping through the descendants
        if( wcgallery_children.classList.contains('sold_out_loop_wrapper_single') ){ 
            var soldout = wcgallery.querySelector('div.sold_out_loop_wrapper');
            wcgallery.addEventListener("mouseout", function( event ) {   
                soldout.style.display = "block";
            }, false);
            wcgallery.addEventListener("mouseover", function( event ) {   
                soldout.style.display = "none";
            }, false);
        } if( wcgallery_children.classList.contains('badge_loop_wrapper_single') ){ 
            var badge = wcgallery.querySelector('div.sold_out_loop_wrapper');
            wcgallery.addEventListener("mouseout", function( event ) {   
                badge.style.display = "block";
            }, false);
            wcgallery.addEventListener("mouseover", function( event ) {   
                badge.style.display = "none";
            }, false);
        } if( wcgallery_children.classList.contains('special_loop_wrapper_single') ){ 
            var special = wcgallery.querySelector('div.sold_out_loop_wrapper');
            wcgallery.addEventListener("mouseout", function( event ) {   
                special.style.display = "block";
            }, false);
            wcgallery.addEventListener("mouseover", function( event ) {   
                special.style.display = "none";
            }, false);
        } else { return } //do nothing
    }
}
window.addEventListener('DOMContentLoaded', function(){
    coming_soon_toggle();
});

</script>

But again, This is also untested.

Hello Elvin,

Na, this does not work. So I guess I go with the approach, to implement more than one scripts. Is that a problem in terms of performance?

Na, this does not work. So I guess I go with the approach, to implement more than one scripts. Is that a problem in terms of performance?

That's unfortunate. But I believe I given you an idea. You're pretty close. This is just a matter of assigning eventlisteners for mouseover/mouseout to the gallery. :)

A bit more line of codes shouldn't be that much of a hit in performance.

But keep in mind, adding things bit by bit will eventually pile up and cause slow downs.

This archived topic is closed to new replies.