Сократить код JavaScript

Рейтинг: 0Ответов: 2Опубликовано: 19.04.2015

Привет.

После нажатия на определённую кнопку открывается блок div с уникальным id. Код js получается большой, потому что повторяется функция. Можно как то уменьшить код?

document.querySelector('button.1').onclick = function() {
var ob = document.getElementById('div1');
if( ob.style.display=='block') { ob.style.display='none'; }
        else  { ob.style.display='block'; }
}
document.querySelector('button.2').onclick = function() {
var ob = document.getElementById('div2');
if( ob.style.display=='block') { ob.style.display='none'; }
        else  { ob.style.display='block'; }
}
document.querySelector('button.3').onclick = function() {
var ob = document.getElementById('div3');
if( ob.style.display=='block') { ob.style.display='none'; }
        else  { ob.style.display='block'; }
}
document.querySelector('#type').onclick = function() {
var ob = document.getElementById('hid1');
if( ob.style.display=='block') { ob.style.display='none'; }
        else  { ob.style.display='block'; }
}
document.querySelector('#type2').onclick = function() {
var ob = document.getElementById('hid2');
if( ob.style.display=='block') { ob.style.display='none'; }
        else  { ob.style.display='block'; }
}

Пробовал вот так:

document.querySelector('button.1','button.2','button.3','#type','#type2').onclick = function() {
        var ob = document.getElementById('div1','div2','div3','hid1','hid2');
        if( ob.style.display=='block') { ob.style.display='none'; }
                else  { ob.style.display='block'; }
        }

но почему-то работает только первый в списке селектор?

HTML

<button class="1"></button>
<div id="div1">блаблабла</div>

...

<span id="type"></span>
<div id="hid1">блаблабла</div>

...

CSS

стилей для элементов нет, скрипт js скрывает div1,div2,div3,hid1,hid2

Ответы

▲ 1Принят

Выделим сначала функцию, которая применяется к нашим элементам. Возьмем для примера первый биндинг вашего кода:

document.querySelector('button.1').onclick = function() {
var ob = document.getElementById('div1');
if( ob.style.display=='block') { ob.style.display='none'; }
        else  { ob.style.display='block'; }
}

Приведем его к следующему виду (обезличим код, вынеся из него реальные значения):

var action_element = 'button.1',
    target_element = 'div1';
document.querySelector(action_element).onclick = function() {
    var ob = document.getElementById(target_element);
    if (ob.style.display == 'block') {
        ob.style.display = 'none';
    } else {
        ob.style.display = 'block';
    }
}

Поскольку теперь в коде мы работаем не с реальными значениями, а с параметрами, то мы можем этот код обернуть в функцию:

function element_binding(action_element, target_element) {
    document.querySelector(action_element).onclick = function() {
        var ob = document.getElementById(target_element);
        if (ob.style.display == 'block') {
            ob.style.display = 'none';
        } else {
            ob.style.display = 'block';
        }
    }
}
var action_element = 'button.1',
    target_element = 'div1';
element_binding(action_element, target_element);

Биндинг можно провести и без использования лишних переменных:

element_binding('button.1', 'div1');

Аналогичным образом вызываем функцию для других параметров.

element_binding('button.1', 'div1');
element_binding('button.2', 'div2');
element_binding('button.3', 'div3');
element_binding('#type', 'hid1');
element_binding('#type2', 'hid2');

Итого полный (и исправленный) код выглядит так:

(function() {

function element_binding(action_element, target_element) {
    var target_element_style = document.getElementById(target_element).style;
    target_element_style.display = 'block';
    document.querySelector(action_element).onclick = function() {
        if (target_element_style.display == 'block') {
            target_element_style.display = 'none';
        } else {
            target_element_style.display = 'block';
        }
    }
}
element_binding('button.class1', 'div1');
element_binding('button.class2', 'div2');
element_binding('button.class3', 'div3');
element_binding('#type', 'hid1');
element_binding('#type2', 'hid2');

})();
<button class="class1">BUTTON_1</button>
<div id="div1">div1</div>

<button class="class2">BUTTON_2</button>
<div id="div2">div2</div>

<button class="class3">BUTTON_3</button>
<div id="div3">div3</div>

<span id="type">SPAN_1</span>
<div id="hid1">hid1</div>

<span id="type2">SPAN_2</span>
<div id="hid2">hid2</div>

Конструкция вида

(function() {
...
})();

используется для того, чтобы не захламлять глобальное пространство. Т.е. все функции и переменные объявленные там не будут конфликтовать с вашими глобальными функциями/переменными.

Для классов использовал более "классные" имена, т.к. class='1' при поиске выдаст ошибку.

Дополнительно в момент инициализации задаю свойство display: block, т.к. иначе для того, чтобы скрыть/показать кнопку пришлось бы нажимать ее два раза.

▲ 3

Как вариант, можно использовать инлайновое навешивание событий ( если кнопки как у вас действительно разные, тут и дивы + кнопки с разными классами )

<button ... ></button>
<div ... ></div>

А вот всего одна функция

 var toggleVisible = function(target) {
    var el = document.querySelector(target);
    el.style.display = (el.style.display == "block") ? "none" : "block";     
 }