dudefromouterspace
dudefromouterspace

Reputation: 35

JavaScript if statement doesn't return true when it should

I have an input panel:

<div id="user_input">...</div>

I have a button:

<input type="button" id="panel_button">...</button>

I have a selector:

function $(id) {
    return document.querySelector(id);
}

I have an event handler:

var button_panel = $('#panel_button');
button_panel.addEventListener('click', fadeUserInputPanel, false);

And finally I have 3 functions for fading in and out the input panel:

var user_input_panel = $('#user_input');
user_input_panel.style.opacity = 1;

function fadeUserInputPanel()
{
    if(user_input_panel.style.opacity == 1)
    {
        fade_out();
    } 
    else if(user_input_panel.style.opacity == 0)
    {
        fade_in();
    }
}

function fade_out() 
{
    if(user_input_panel.style.opacity > 0) 
    {
        user_input_panel.style.opacity -= 0.1;
        setTimeout(fade_out, 50);
    }
}

function fade_in() 
{
    if(user_input_panel.style.opacity < 1) 
    {
        user_input_panel.style.opacity += 0.1;
        setTimeout(fade_in, 50);
    }
}

The problem is the following:

When I load up the page, the input panel can be seen - since its opacity's value is 1.

Then I click on the panel_button, which starts to make the input panel fade out. It works just perfectly fine, so the opacity goes straight to 0 and the panel slowly disappears.

But when I click on the panel_button again, it starts to make the input panel fade in, however it stops when the input panel's opacity is 0.1, and it does not go any further.

But according to the 'fade_in()' function - if the opacity is less than 1 - it should continue fading the panel in. Why doesn't it work?

Upvotes: 0

Views: 60

Answers (2)

Alnitak
Alnitak

Reputation: 339796

This happens because style.opacity is not a number, but a string.

> document.body.style.opacity = 0
0
> document.body.style.opacity 
"0"
> document.body.style.opacity += 0.1 
"00.1"
> document.body.style.opacity += 0.1 
"0.10.1"
> document.body.style.opacity += 0.1 
"0.10.1"

The subtraction for fade_out() works OK, but only because the -= operator doesn't have concatenation semantics and will always coerce the arguments to be numbers.

To fix, manually coerce the opacity to a number:

function fade_in() {
    var opacity = +user_input_panel.style.opacity;
    if (opacity < 1) {
        user_input_panel.style.opacity = opacity + 0.1;
        setTimeout(fade_in, 50);
    }
}

Upvotes: 3

Bryan Ray
Bryan Ray

Reputation: 929

You can simply parseFloat on the opacity and it should be fixed.

function fade_in() 
{
    if(user_input_panel.style.opacity < 1) 
    {
        user_input_panel.style.opacity = parseFloat(user_input_panel.style.opacity) + 0.1;
        console.log(user_input_panel.style.opacity);
        setTimeout(fade_in, 50);
    }
}

Here is a working example: https://jsfiddle.net/bryanray/1c9oo5k5/

Upvotes: 0

Related Questions