2

I'm trying to understand javascript and javascript functions. This function is used to change the look of a button.

function changeButton(){
    btn.style.backgroundColor = btn.style.backgroundColor == "black" ? "white" : "black";
    btn.style.color = btn.style.color == "white" ? "black" : "white";
    btn.innerHTML = btn.innerHTML == 'GOOD JOB' ? 'CLICK ME' : 'GOOD JOB';
}

It works just fine. But when I look at this function I see a lot of repetition. The basic structure seems to be element = element == value1 ? value2 : value1

So in my mind this should work:

function toggleValue(elem, val1, val2){
    elem = elem == val1 ? val2 : val1
}

function changeButton(){
    var x = btn.style.backgroundColor
    var y = btn.style.color
    var z = btn.innerHTML
    toggleValue(x, 'white', 'black')
    toggleValue(y, 'black', 'white')
    toggleValue(z, 'CLICK ME', 'GOOD JOB')
}

But it does not work and I don't understand why. Can someone tell me why this doesn't work? And is there a way to make it work?

I0_ol
  • 1,054
  • 1
  • 14
  • 28
  • 2
    A better way would be to use CSS and `classList.toggle` to turn the "active" class on and off. – georg Jan 29 '18 at 13:14
  • `x.y = ...` modifies the property of an object. `x = ...` reassigns a local variable. – deceze Jan 29 '18 at 13:15
  • `var x = btn.style.backgroundColor`, in this you are just copying a `value` which is there in the `backgroundColor` property. This will not act as a `reference`. – Bharadwaj Jan 29 '18 at 13:16

4 Answers4

4

It does not work, because you hand over a primitive value an not a reference to the property.

function toggleValue(elem, prop, val1, val2){
    elem[prop] = elem[prop] == val1 ? val2 : val1
}

function changeButton(){
    toggleValue(btn.style, 'backgroundColor', 'white', 'black')
    toggleValue(btn.style, 'color', 'black', 'white')
    toggleValue(btn, 'innerHTML', 'CLICK ME', 'GOOD JOB')
}
Redu
  • 25,060
  • 6
  • 56
  • 76
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
3

Because you are passing the String which is immutable.

You can create one more argument - property.

function toggleValue(elem, prop, val1, val2){
    elem[prop] = elem[prop] == val1 ? val2 : val1
}

function changeButton(){
    var x = btn.style;
    var y = btn.style;
    var z = btn;
    toggleValue(x, "backgroundColor", 'white', 'black');
    toggleValue(y, "color", 'black', 'white');
    toggleValue(z, "innerHTML", 'CLICK ME', 'GOOD JOB');
}
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
1

function toggleValue(elem, val1, val2, ButtonStyleType) {        
        elem = elem == val1 ? val2 : val1;
        if (ButtonStyleType == 'backgroundColor')
            btn.style.backgroundColor = elem;
        else if (ButtonStyleType == 'color')
            btn.style.color = elem;
        else if (ButtonStyleType == 'innerHtml')
            btn.innerHTML = elem;
    }
    function changeButton() {        
        var x = btn.style.backgroundColor;
        var y = btn.style.color;
        var z = btn.innerHTML;
        toggleValue(x, 'green', 'yellow', 'backgroundColor');
        toggleValue(y, 'black', 'Orange', 'color');
        toggleValue(z, 'Default', 'GOOD JOB', 'innerHtml');
    }
<button id="btn" style="background-color:green; color:black;">Default</button><br />
        <br />
        <a style="cursor:pointer;color:blue;" onclick="changeButton();">Click here to update button style</a>
bindi.raval
  • 262
  • 1
  • 7
0

You have to understand the difference between pass by value and pass by reference to know more about that click here

RaM PrabU
  • 415
  • 4
  • 16