2013-04-17 4 views
2

Я играл с javascript для создания выпадающего списка, который показывает div в зависимости от выбранного параметра.Javascript show div on HTML select

Весь код можно увидеть здесь:

http://jsfiddle.net/nmdTy/

var select = document.getElementById('test'), 
onChange = function(event) { 
    var shown = this.options[this.selectedIndex].value == 1; 
    document.getElementById('hidden_div').style.display = shown ? 'block' : 'none'; 
}; 

Я хочу знать, как я могу оптимизировать этот код и удалить повторения - может быть какой-то цикл?

+2

Что вы имеете в виду, удаляя повторение? – dreamweiver

+1

@ dreamweiver вы нажали на скрипку? –

+0

вы можете импровизировать свой код еще больше, более того, это redundant.write один обработчик, основанный на значении 1 или 2, задающем стиль. – dreamweiver

ответ

1

Вам не нужны два обработчика событий, вы можете использовать переменные (показано ниже), чтобы определить, какой из div должен отображаться или скрываться.

var select = document.getElementById('test'), onChange = function(event) { 
    var div1 = 'hidden_div'; 
    var div2 = 'hidden_div2'; 

    var index1 = this.options[this.selectedIndex].value == 1; 
    var index2 = this.options[this.selectedIndex].value == 2; 

    if(index1 || index2){ 
     document.getElementById(div1).style.display = index1 ? 'block' : 'none'; 
     document.getElementById(div2).style.display = index2 ? 'block' : 'none'; 
    } 
    else{ 
     document.getElementById(div1).style.display = 'none'; 
     document.getElementById(div2).style.display = 'none'; 
    } 
}; 

// attach event handler 
if (window.addEventListener) { 
    select.addEventListener('change', onChange, false); 
} else { 
    // of course, IE < 9 needs special treatment 
    select.attachEvent('onchange', function() { 
     onChange.apply(select, arguments); 
    }); 
} 

Working Fiddle

+0

У вас все еще есть повторение. –

+0

@ TomášZato Какое повторение вы имеете в виду? Я что-то посмотрел? –

+0

Конечно, ОП не определил, что он подразумевает под повторением, но мне не очень нравится писать слишком много утверждений 'if'. Это просто мое мнение. –

0

Я не совсем уверен, что вы имеете в виду под «повторения», но я думаю, что вы не хотите вводить каждый каждый из div с быть скрыты/показано на рисунке.
В такой задаче может быть несколько подходов. Наиболее универсальным является наличие id div в отдельном массиве. Затем вы можете скрыть все, кроме выбранного div.

var divs = ["hidden_div1", "special_hidden", "one_more_hidden"]; 
var select = document.getElementById('test'); 
var onchange = function(event) { //Use var! 
    var shown = this.options[this.selectedIndex].value; 
    for(var i=0; i<window.divs.length; i++) { //It would be more effective to save last shown div in a variable, but I've chosen this aproach with loop 
     var div = document.getElementById(window.divs[i]); 
     if(div!=null) { 
      if(i==shown) 
      div.style.display="block"; 
      else 
      div.style.display="none"; 
     } 
    } 
}; 
select.addEventListener("change", onchange); //Could type the function right here, without using "onchange" variable 

В моем коде, <option> значение представляет собой индекс в массиве. Вот jsFiddle.

0

Делегирование события изменения в IE < 9 - это боль. Возможно, check this question to see how it's done, но это не то, что вы называете элегантным.

Но ваш код не передает событие, так что просто прикрепление обработчика непосредственно в onload случае следует сделать трюк (и это X-совместимый браузер):

document.getElementById('test').onchange = function(e) 
{ 
    e = e || window.event;//the only IE headache 
    var shown = this.options[this.selectedIndex].value == 1; 
    document.getElementById('hidden_div').style.display = shown ? 'block' : 'none'; 
    //^^ could keep a reference to this in a closure 
}; 

Полный код (с onload и закрытие ссылки на скрытые DIV иpreventing memory leaks in ie) должен выглядеть следующим образом:

var winLoad = function(e) 
{ 
    var hiddenDiv = document.getElementById('hidden_div'); 
    document.getElementById('test').onchange = function(e) 
    { 
     var shown = !!(this.option[this.selectedIndex].value == 1);//to be safe, coerce to bool 
     hiddenDiv.style.display = shown ? 'block' : 'none'; 
    }; 
    if (window.addEventListener) 
    { 
     return window.removeEventListener('load',winLoad,false); 
    } 
    return window.detachEvent('onload',winLoad); 
}; 
if (window.addEventListener) 
{ 
    window.addEventListener('load',winLoad,false); 
} 
else 
{ 
    window.attachEvent('onload',winLoad); 
} 

, что должно работать на всех основных браузерах, даже IE7 (возможно IE6 Тоже)

1

Другой код:

var select = document.getElementById('test'), 
    nbItems = 2, 
    onChange = function (event) { 
     var val = this.options[this.selectedIndex].value; 

     for (var i = 1; i <= nbItems; i++) { 
      document.getElementById('hidden_div' + i).style.display = val == i ? 'block' : 'none'; 
     } 
    }; 

http://jsfiddle.net/nmdTy/11/

+0

Это то, что я буду делать, решая реальную проблему. –

+0

Это очень просто, но очень элегантно одновременно, мне очень нравится, и это именно то, что я делал после.Но где это могло бы оставить меня, если бы у divs «hidden_div1/2» были разные имена, скажем что-то вроде «some_div» и «this_other_div»? – twigg

+0

@twigg вы можете использовать массив (как Томаш Зато сделал в своем решении), чтобы соответствовать divs ... Смотрите эту скрипку: http://jsfiddle.net/nmdTy/17/. –