0

I am trying to create an if statement in jquery that checks to see if the opacity is .3, but it does not work.

if ($(this).css('opacity')==.3) {$(this).fadeTo(500,1);}

Am I formatting the opacity incorrectly? I also tried 0.3 to no avail.

Background:

I'm working with a fade effect, where an objects fades in when you scroll past it and fades out when you scroll up.

myfunkyside kindly showed me how to do this here: Fade In on Scroll Down, Fade Out on Scroll Up - based on element position in window

myfunkyside's original jsfiddle: http://jsfiddle.net/b7qnrsrz/1/

In this instance, the fade goes from 0 opacity to 1 and back. I want to go from .3 to 1 and back instead.

I tried to replace

if (objectBottom < windowBottom) {
    if ($(this).css('opacity')==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
    if ($(this).css('opacity')==1) {$(this).fadeTo(500,0);}
}

with

if (objectBottom < windowBottom) {
    if ($(this).css('opacity')==.3) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
    if ($(this).css('opacity')==1) {$(this).fadeTo(500,.3);}
}

but it does not work. Here's my attempt on jsfiddle: http://jsfiddle.net/b7qnrsrz/3/

Thanks for taking a look at this!

Community
  • 1
  • 1
minimographite
  • 333
  • 1
  • 3
  • 7

5 Answers5

2

The issue is that floating point numbers in JavaScript are not always strictly .3 or .5, some other digits get added to the end as well. Try putting the first condition on top, and jump to the other if it's false, since it theory, you shouldn't have other states.

I would also suggest assigning $(this) to a variable to prevent jQuery from having to create an instance of the same element 3 times.

var $this = $(this),
    opacity = $this.css('opacity');
if (objectBottom < windowBottom){
    if (opacity != 1) $this.stop().fadeTo(500,1);
}
else if (opacity == 1) $this.stop().fadeTo(500,.3);

I also added .stop(), because if someone is scrolling up and down rapidly for whatever reason, the animation queue on the element may fill up and cause a pulsing effect due to all fading animations still being in the queue. Stop prevents this by clearing the animations from the queue, and thus executing the following animation instantaneously.

Also, this

$(window).scroll(function() {fade();});

can be shortened just to

$(window).scroll(fade);

Working example:

$(window).on("load",function() {
    function fade() {
        $('.fade').each(function() {
            var objectBottom = $(this).offset().top + $(this).outerHeight(),
                windowBottom = $(window).scrollTop() + $(window).innerHeight(),
                $this = $(this),
                opacity = $this.css('opacity');
            
            if (objectBottom < windowBottom){
                if (opacity != 1) $this.fadeTo(500,1);
            }
            else if (opacity == 1) $this.fadeTo(500,.3);
        });
    }
    fade();
    $(window).scroll(fade); //Fade in elements during scroll
});
.fade {
    margin: 50px;
    padding: 50px;
    background-color: lightgreen;
    opacity: .3;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
    <div class="fade">Fade In 01</div>
    <div class="fade">Fade In 02</div>
    <div class="fade">Fade In 03</div>
    <div class="fade">Fade In 04</div>
    <div class="fade">Fade In 05</div>
    <div class="fade">Fade In 06</div>
    <div class="fade">Fade In 07</div>
    <div class="fade">Fade In 08</div>
    <div class="fade">Fade In 09</div>
    <div class="fade">Fade In 10</div>
</div>
SeinopSys
  • 8,787
  • 10
  • 62
  • 110
1

Floating points are subject to imprecision, for more info, go to floating-point-gui.de.

What you need to do is use a "epsilon": a acceptable range of difference of your desired and the actual value.

abs(VALUE) - COMPARE < EPSILON

So your comparsion should be:

Math.abs($(this).css('opacity')) - .3 < 0.01

For a 0.01 acceptable error. This might be more specific, but I don't think it would be necessary for this case.

1

Just use javascript Math to get the opacity value with one decimal:

if (Math.round($(this).css('opacity') * 10) / 10 == .3) {
  $(this).fadeTo(500,1);
}
alpipego
  • 3,223
  • 2
  • 17
  • 28
  • @miminographite if you will use this solvation, than ure able to use different opacity options, because the if else just give you 2 options... just want you to keep that in mind ;) – Mephiztopheles Nov 02 '14 at 21:58
0

You can do it like this:

    $('.fade').each(function () {
        /* Check the location of each desired element */
        var objectBottom = $(this).offset().top + $(this).outerHeight();
        var windowBottom = $(window).scrollTop() + $(window).innerHeight();

        var opacityPercentage = parseInt($(this).css("opacity") * 100);
        /* If the object is completely visible in the window, fade it in */
        if (objectBottom < windowBottom) { //object comes into view (scrolling down)
            if (opacityPercentage == 30) {
                $(this).fadeTo(500, 1);
            }
        } else { //object goes out of view (scrolling up)
            if (opacityPercentage == 100) {
                $(this).fadeTo(500, 0.3);
            }
        }
    });
Johan Karlsson
  • 6,419
  • 1
  • 19
  • 28
0

You could do what everyone else is saying, or since you're only dealing with two case (positive/negative test), you could use ==1 and !=1, instead of ==.3. Also, it's jQuery, make sure to use .stop() with transitions/animations.

http://jsfiddle.net/b7qnrsrz/16/

vol7ron
  • 40,809
  • 21
  • 119
  • 172
  • You need more logic in your function. Every time you scroll you're calling the function, which is stacking the event (and adding time). Using `stop(true,true)` usually would be an answer, however you don't want the animation completing immediately. Therefore you need code to detect current animations, and not stack them, but to change the animation if it goes beyond the scope of the window. – vol7ron Nov 03 '14 at 18:23
  • This seemed to be the simplest solution. Thanks! I modified it a bit, because of a delay in the animation, so I took out the if statement's '.stop()' and it appears to be working exactly as intended. [jsfiddle](http://jsfiddle.net/b7qnrsrz/20/) – minimographite Nov 04 '14 at 03:44
  • The reason I put those in there was for when you scrolled up and down very quickly. Try it out and take notice to what happens when you do. Nevermind, I thought you took it out of both and it seems you only took it out of the one, so it might work. – vol7ron Nov 04 '14 at 14:15