Link to home
Start Free TrialLog in
Avatar of Jonathan Greenberg
Jonathan GreenbergFlag for United States of America

asked on

How to call jQuery function on CSS change

I have an image slider plugin in my Joomla website, and I want to make the opacity of each slider image gradually increase after initial display. To do this, I have a jQuery function I'd like to call whenever a particular CSS transition occurs: div's z-index value. As each slide becomes the featured one, its container div's z-index goes from 10 to 20.

Here's my jQuery function so far:

$(document).ready(function() {
	$(".sp-image").fadeTo(4000, 0.2);
});

Open in new window


That function fades all slider images one time only, on page load. I'd like to instead call the function whenever the "z-index" property of <div class="sp-slide"> changes to a value of 20 (from 10).

How can my function be written so it's called whenever the z-index of <div class="sp-slide"> changes to 20? (Assuming this is even doable.)

Thanks!

Regards,
Jon
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Not sure you can hook into CSS changes. Instead you could maybe hook into whatever is causing the z-index to change (assuming it's some other javascript elsewhere in your page - part of the slider code maybe). You may also want to take a look at the slider plugin (if that's what you're using) as most of them tend to have some way to configure the transitions already built in.
Avatar of Jonathan Greenberg

ASKER

Ok, Chris, thanks. But I'm really hesitant - and it's pretty far over my head - to get into the script that's affecting the z-index. That script is unbelievably long.

How about this. I just observed that the containing image div "grows" a class whenever it's active. Is there a way for a jQuery function to listen to all (3) divs of that class, 'sp-slide', and execute something when the additional class, 'sp-selected', shows up?
Hmm. Not easily doable, unless you're really comfortable messing with scripts. Having a quick google around and it looks like it could possibly be done with a MutationObserver, but it's not something I've ever done or even considered doing.

Have you checked the plugin's documentation. Like I said most offer some way to override the transition and some will even offer an event function for when the slider changes. That's really where you should be hooking into this.

If it isn't built in then there probably isn't an easy way to add this functionality.
No, it's definitely not something that's built in to the plugin's functionality.

But... I just found the code in the plugin's script that's adding the class! Now I need help adding my own action.

Here's the code that's adding the class:

// Re-assign the 'sp-selected' class to the currently selected slide
this.$slides.find( '.sp-selected' ).removeClass( 'sp-selected' );
this.$slides.find( '.sp-slide' ).eq( this.selectedSlideIndex ).addClass( 'sp-selected' );

Open in new window


How can I hook into this last line and add my own action?

Thank you, Chris!
You should just be able to add your fade onto the end of it:

this.$slides.find( '.sp-slide' ).eq( this.selectedSlideIndex ).addClass( 'sp-selected' ).fadeTo(4000, 0.2);

Open in new window


You'll probably have to find some way to reset the opacity back to 1 again, otherwise it's still likely to be set to 0.2 the next time the slide comes around.
ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Chris, thank you, that was so thoughtful of you!

I'm actually not using Slider Pro, but AP Smart LayerSlider. The strange thing is that the code appears very similar. Looks like someone borrowed from someone!

Assuming for a moment that they're similar enough that what you're suggesting would apply to both, I'm missing one thing, which is: what am I supposed to do with the first parenthetical text - '#my-slider' ? Would that get replaced with something?
It's working! I don't want you to take anymore time on this, as I've figured out the answer to my question. I'll post back here shortly.
OK. As it's a Joomla plugin, you may not easily be able to get at the actual initialisation code, which is where you'd need to hook up the events. The code I posted above assumed you were initialising the PlugIn yourself. The #my-slider part is basically the HTML selector for the slider, so in my example it would turn a DIV with an ID of my-slider into the animated Slider.

I don't know Joomla, so can't offer you any advice on how to get at the init code for a plug-in. As it's a commercial plugin, you should have access to some kind of support from the developers, so an email to them may get you precisely the help you need.
Actually, this is working perfectly, except for one thing. It's doing exactly what I said I needed to do, but I was a little off in saying what I need. I need to affect the opacity of an image 2 levels down in the dom; so the child's child of the div that's currently being acted upon.

Here's the script that's now working:

$('#ap-smart-layerslider-mod_171').sliderPro({
	gotoSlideComplete: function( event ) {
		this.getSlideAt(event.index).$slide.fadeTo(5000, 0.2);
		this.getSlideAt(event.previousIndex).$slide.css('opacity', 1);
	}
});

Open in new window


I need to target the class 'sp-image', which is an image and the child's child of the div currently being targeted.

What do you think - can it be done?
Got it!

<script type="text/javascript">
jQuery(function($) { 
    $('#ap-smart-layerslider-mod_171').sliderPro({
        gotoSlideComplete: function( event ) {
            this.getSlideAt(event.index).$slide.find(".sp-image").fadeTo(5000, 0.2);
            this.getSlideAt(event.previousIndex).$slide.find(".sp-image").css('opacity', 1);
        }
    });
});
</script>

Open in new window


All that's missing is that the very first slide isn't being affected. This code is kicking in at each transition, but it's doing noting on the very first slide. Maybe I should do this with $( document ).ready() ?
And here it is:

<script type="text/javascript">
jQuery(function($) { 
    $(document).ready(function() {
        $(".sp-selected").find(".sp-image").fadeTo(5000, 0.2);
    });
    $('#ap-smart-layerslider-mod_171').sliderPro({
        gotoSlideComplete: function( event ) {
            this.getSlideAt(event.index).$slide.find(".sp-image").fadeTo(5000, 0.2);
            this.getSlideAt(event.previousIndex).$slide.find(".sp-image").css('opacity', 1);
        }
    });
});
</script>

Open in new window


Chris, if you think there's any better way to do any of this than what I've done, please let me know. Otherwise, I think I'm good to go.

Thanks so much for your help!
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Chris, that works perfectly!

Just so I understand, can you tell me why this is a preferable method to hooking into document.ready? Less taxing on the page as it loads, perhaps?
Hey Jonathan,

It's really just about keeping things in a sensible order. The document.ready block will fire when the document is ready i.e. the DOM has loaded. Now in your case, the DOM will be loaded before the Slider has been activated which may cause the first slider to fade before it's even part of the slider.

By adding it to the init event, you know it won't fire until the Slider is ready.

Also, for me, it just 'feels' right to keep all the Slider code in the slider methods.
Thanks so much for your help on this, Chris! And thanks for letting me in on your thinking - it really helps.

All the best,
Jonathan
No worries Jonathan.

Glad you've got it working.