HackYa HackYa - 15 days ago 8
Javascript Question

How to combine multiple onclick events/elements

I have this toggle function which has multiple buttons.

var button1 = document.querySelector('#button1');
var button2 = document.querySelector('#button2');
var button3 = document.querySelector('#button3');

var toggleState = function (elem, one, two) {
var elem = document.querySelector(elem);
elem.setAttribute('data-state', elem.getAttribute('data-state') === one ? two : one); //ternary operator
};

button1.onclick = function (e) {
toggleState('#div1', 'open', 'closed');
e.preventDefault();
};

button2.onclick = function (e) {
toggleState('#div2', 'open', 'closed');
e.preventDefault();
};

button3.onclick = function (e) {
toggleState('#div3', 'open', 'closed');
e.preventDefault();
};


I do realize this looks very retarded. I've tried querySelectorAll to combine variables but it doesn't work. I think I know why. But I can't figure out a way to write the script more eloquently. (scratch eloquently. respectable is a better word)

How can I combine variables and onclicks so that the code does not look so redundant/retarded/laughable?

I am just trying to learn to write javascript properly. Have been addicted to jQuery for so long & I've realized I actually don't know how to write javascript. So I am trying to learn.

Answer

Consider a solution similar to the one below. Instead of copying the event handler per element, you could process each of the elements in a loop.

If the element ids are consistent, you could make it even briefer by only specifying the number of toggles and generating the ids on the fly.

var toggles = {
    '#button1': '#div1',
    '#button2': '#div2',
    '#button3': '#div3'
};

Object.keys(toggles).forEach(function(toggle) {
    document.querySelector(toggle).onclick = function (e) {
        toggleState(toggles[toggle], 'open', 'closed');
        e.preventDefault();
    };
});

function toggleState(elem, one, two) {
    var elem = document.querySelector(elem);
    elem.setAttribute('data-state', elem.getAttribute('data-state') === one ? two : one);
};