Я пытаюсь создать сложную форму с «гибкими» элементами выбора / выбора для простоты использования, которые должны проявляться только в зависимости от выбора пользователя. Другими словами, если пользователь выбирает определенную опцию в одной группе <select>
, то новый набор опций должен проявить себя во второй группе <select>
. Моя ситуация на бит более сложная, чем эта, но это краткое изложение ее поведения.
Тем не менее, я хочу более приятный интерфейс, чем у меня сейчас; а именно, я хочу, чтобы форма поддерживалась и идеально подходила для всех браузеров.
У меня есть один конкретный элемент <select>
(давайте назовем этот элемент 'selectA'), который имеет список различных опций, а именно, 'optionA-1', 'optionA-2' и 'optionA-3'.
У меня есть еще один элемент <select>
, называемый «selectB», который должен раскрываться только при выборе «optionA-1» или «optionA-3». У «selectB» также есть четыре других параметра, с острым названием «optionB-1», «optionB-2», «optionB-3» и, конечно, «optionB-4».
Наличие «selectB» исчезает и появляется вновь по желанию - это обычное дело - всего лишь немного JS и, как известно, «магически» отзывчивая форма!
Вот проблема, однако: 'optionB-3' и 'option-B-4' должны быть видимы, только если выбрана опция 'optionA-3'; в противном случае они не должны отображаться.
Это не так уж много, что я не могу сделать это, но я хочу, чтобы дизайн был четким (то есть без лишних пробелов, где он не нужен) и не был бы слишком зависимым от JavaScript (так как пользователи могут включать или отключать его по своему желанию, и я не хочу, чтобы основная функциональность нарушалась).
Вот примерно структура формы, как есть:
<form>
<select name='selectA' id='selectA' onchange='showSelectB()'>
<option value='DEFAULT-A'>---Choose one---</option>
<option value='optionA-1'>OptionA-1</option>
<option value='optionA-2'>OptionA-2</option>
<option value='optionA-3'>OptionA-3</option>
</select>
<select name='selectB' id='selectB'>
<option value='DEFAULT-B'>---Choose another one---</option>
<option value='optionB-1'>OptionB-1</option>
<option value='optionB-2'>OptionB-2</option>
<option class='hideable' value='optionB-3'>OptionB-3</option>
<option class='hideable' value='optionB-4'>OptionB-4</option>
</select>
</form>
Кажется довольно просто, верно? Хорошо, теперь функция JavaScript делает «selectB» более «гибкой / отзывчивой» (подразумевается, что это находится в том же файле в элементе <script>
):
function showSelectB()
{
var selectABox = document.getElementById("selectA");
var selectedValue = selectABox.options[selectABox.selectedIndex].value;
var selectBBox = document.getElementById("selectB");
if(selectedValue == "optionA-1" || selectedValue == "optionA-3")
{
selectBBox.style.display = ""; //Ta-da!
var options = document.getElementsByClassName("hideable");
var length = options.length;
if(selectedValue == 'optionA-3')
{
for(var i = 0; i < length; i++)
{
options[i].style.display = ""; //Now you see me...
}
}
else
{
for(var i = 0; i < length; i++)
{
options[i].style.display = "none"; //...Now you don't
}
}
}
else
{
selectBBox.style.display = "none"; //Disappear!
}
}
//I was being lazy here
document.getElementById("selectB").style.display = "none";
(Теперь я знаю, что синтаксис jQuery чище, но в этом случае я предпочитаю хороший старый JavaScript).
Если вы проверите это, вы увидите, что оно работает нормально; опции приходят и уходят, как и ожидалось ... за исключением одного предупреждения:
- Когда опция «optionA-1» выбрана в «selectA», «selectB» возвращает эти ужасные пробелы, когда опции B-3 и B-4 больше не отображаются (по крайней мере, они делают это в моей версии Microsoft Edge, который мне показался довольно странным, поскольку это больше похоже на то, как должен работать атрибут
visibility
); для меня это выглядит довольно некрасиво.
Заменитель, который я пытался использовать для этого кода JavaScript, заключался в том, чтобы рассматривать «скрываемые» параметры как дочерние узлы «selectB» и добавлять или удалять их всякий раз, когда «optionA-3» был выбран или «не выбран», но это казалось ужасным грязный и подверженный ошибкам (а именно, он добавил бы слишком много опций, если бы я выбрал «optionA-3» прямо из ворот). Возможно, я где-то пренебрегал условием if или else, но оно просто не работало в значительном количестве моих тестовых прогонов.
Мне было интересно, может быть, существует третья альтернатива, которая поддерживает адаптивность формы, но не запутывается в этих несоответствиях, которые всплывают в «selectB» (по крайней мере, в Microsoft Edge и IE).
РЕДАКТИРОВАТЬ: Вот рабочий фрагмент, как и требовалось.
function showSelectB()
{
var selectABox = document.getElementById("selectA");
var selectedValue = selectABox.options[selectABox.selectedIndex].value;
var selectBBox = document.getElementById("selectB");
if(selectedValue == "optionA-1" || selectedValue == "optionA-3")
{
selectBBox.style.display = ""; //Ta-da!
var options = document.getElementsByClassName("hideable");
var length = options.length;
if(selectedValue == 'optionA-3')
{
for(var i = 0; i < length; i++)
{
options[i].style.display = ""; //Now you see me...
}
}
else
{
for(var i = 0; i < length; i++)
{
options[i].style.display = "none"; //...Now you don't
}
}
}
else
{
selectBBox.style.display = "none"; //Disappear!
}
}
//I was being lazy here
document.getElementById("selectB").style.display = "none";
<form>
<select name='selectA' id='selectA' onchange='showSelectB()'>
<option value='DEFAULT-A'>---Choose one---</option>
<option value='optionA-1'>OptionA-1</option>
<option value='optionA-2'>OptionA-2</option>
<option value='optionA-3'>OptionA-3</option>
</select>
<select name='selectB' id='selectB'>
<option value='DEFAULT-B'>---Choose another one---</option>
<option value='optionB-1'>OptionB-1</option>
<option value='optionB-2'>OptionB-2</option>
<option class='hideable' value='optionB-3'>OptionB-3</option>
<option class='hideable' value='optionB-4'>OptionB-4</option>
</select>
</form>
Интересно, что я не достаточно хорошо протестировал это в браузерах; Теперь я замечаю, что он отлично работает на Chrome и Firefox, но, к сожалению, не на Microsoft Edge (и IE совершенно не работает). Итак, ясно, что это кросс-браузерная проблема. Проблема в том, откуда возникла проблема с кроссбраузерностью?