Javascript - innerHTML не работает с меню выбора HTML

На моей странице HTML у меня есть 2 меню выбора с идентификаторами "месяц" и "день" - "день" пуст при загрузке страницы, "месяц" имеет 12 параметров со значениями 1-12, соответствующими январю - декабрю.

"month" имеет событие onchange, которое вызывает эту функцию:

function showOutboundDays(month)
{
if(month==4 || month==6 || month==9 || month==11)
    document.getElementById('day').innerHTML='<option value="1">1</option><option value="2">2</option>'; etc. up to 30
else if(month==2)
    document.getElementById('day').innerHTML='<option value="1">1</option>'; etc. up to 28
else 
    document.getElementById('day').innerHTML='<option value="1">1</option>'; etc. up to 31
}

(just imagine there are braces around the option tags to help you see...)

Я думаю, что довольно ясно видно, чего я пытаюсь достичь ... и все работает нормально, за исключением innerHTML выбора с идентификатором «день» вообще не заполняется, независимо от того, какой месяц вы выбираете. И я знаю, что проблема связана с этим этапом функции, потому что, когда я меняю код if, elseif и else, который нужно выполнить, на предупреждения или что-то подобное, он работает нормально.

Кто-нибудь знает, в чем проблема с innerHTML?

Спасибо

РЕДАКТИРОВАТЬ: Использование Firefox 3.6


person Deacon    schedule 29.04.2010    source источник
comment
Моя проблема была innerHtml против innerHTML :)   -  person Siddharth    schedule 05.09.2018


Ответы (8)


Это известная проблема для IE.

Статья базы знаний с обходным решением: http://support.microsoft.com/kb/276228

Также: дублирование: замена внутреннего HTML не отражает

РЕДАКТИРОВАТЬ: Вот мой рабочий образец, основанный на вашем коде:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <title>Selects</title>
 <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
 <style rel="stylesheet" type="text/css">
 </style>
 <script>
function showOutboundDays(month) 
{ 
    if(month==4 || month==6 || month==9 || month==11) 
        document.getElementById('day').innerHTML='<option value="1">1</option><option value="2">2</option>';
    else if(month==2) 
        document.getElementById('day').innerHTML='<option value="1">3</option><option value="1">4</option>';
    else  
        document.getElementById('day').innerHTML='<option value="1">5</option><option value="1">6</option>';
}
 </script>
 </head>
<body>
    <select onchange="showOutboundDays(this.value);">
        <option value="1">January</option>
        <option value="2">February</option>
        <option value="3">March</option>
        <option value="4">April</option>
        <option value="5">May</option>
        <option value="6">June</option>
        <option value="7">July</option>
        <option value="8">August</option>
        <option value="9">September</option>
        <option value="10">October</option>
        <option value="11">November</option>
        <option value="12">December</option>
    </select>
    <br />
    <select id="day">
    </select>
</body>
</html>
person David    schedule 29.04.2010
comment
Извините, я должен был добавить, я использую Firefox - person Deacon; 29.04.2010
comment
Можете ли вы отредактировать свой пост, выделить код и щелкнуть значок кода в редакторе, чтобы фигурные скобки прошли правильно. Нужно точно видеть, что вы пытаетесь сделать. - person David; 29.04.2010
comment
Я протестировал ваш код, и он работал у меня в Firefox после того, как я удалил ваши комментарии и добавил точки с запятой для каждой строки в if/else и т. д. Я могу опубликовать то, что я изменил, если вам это все еще нужно, но я рекомендую ответ RoToRa вместо использования innerHTML, тем более что innerHTML не будет работать в IE - person David; 29.04.2010
comment
Не могли бы вы опубликовать версию моего кода с вашими изменениями? Как я только что попробовал после того, как избавился от комментариев и добавил точки с запятой, как вы сказали, и это все еще не работает! Спасибо - person Deacon; 29.04.2010

Я бы предложил просто не использовать innerHTML для select - это кажется неправильным. Элементы select имеют простые в использовании методы для добавления новых опций:

`document.getElementById('day').options.add(new Option("1", "1"))`

параметры в вышеуказанном создании объекта:

new Option("optionText", "optionValue")

Просто хотел добавить к этому ответу, потому что он может прояснить для кого-то, кто доберется до этого поста.

person RoToRa    schedule 29.04.2010

Вы не должны использовать innerHTML для изменения тегов. Вы должны использовать removeChild(element); и appendChild(element);

Сначала вы устанавливаете поле выбора в переменной для удобочитаемости и редактирования;

var select = document.getElementById('days');

Затем вы очищаете поле выбора

while ( select.childNodes.length >= 1 )
{
    select.removeChild(select.firstChild);       
}

Наконец, вы снова заполняете его соответствующими значениями.

for(var i=1;i<=days;i++)
{
    newOption = document.createElement('option');
    newOption.value=i;
    newOption.text=i;
    select.appendChild(newOption);
}

Итак, в конце с вашим кодом и моим кодом здесь вы получите следующее:

function showOutboundDays(month, year)
{
    var days=null;

    if(month==4 || month==6 || month==9 || month==11)
        days=30;
    else if(month==2)
    {
        //Do not forget leap years!!!
        if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) //Provided by Justin Gregoire
        {
            days=29;
        }
        else
        {
            days=28;
        }
    }
    else 
        days=31;


    var select = document.getElementById('days');

    while ( select.childNodes.length >= 1 )
    {
        select.removeChild(select.firstChild);       
    }

    for(var i=1;i<=days;i++)
    {
        newOption = document.createElement('option');
        newOption.value=i;
        newOption.text=i;
        select.appendChild(newOption);
    }
}

Високосные годы теперь включены!

person Jonathan Czitkovics    schedule 29.04.2010
comment
Используйте newOption.text вместо innerHTML. Более надежен и позволяет избежать проблем с экранированием HTML. - person bobince; 29.04.2010
comment
Вы можете проверить свою логику на предмет високосных лет — они случаются примерно раз в 4 года. - person Joe; 29.04.2010
comment
если (год % 400 == 0 || (год % 4 == 0 && год % 100 != 0)) дней = 29; еще дней = 28; - person Justin Gregoire; 29.04.2010
comment
Спасибо, что указали на это для меня и нашли это тоже! Изменил мой код и оставил кредит там, где он должен. - person Jonathan Czitkovics; 29.04.2010
comment
Привет Джонатан, спасибо за вашу помощь - я пытался ввести код, но, к сожалению, я просто получаю пустое поле выбора в течение нескольких дней. Не совсем уверен, в чем дело, я использую Firefox 3.6 на OSX, если это имеет значение - person Deacon; 29.04.2010

Это немного хак, но он крошечный и работает как в FF, так и в IE в качестве обходного пути к невозможности IE изменить innerHTML для выбранных элементов.

function swapInnerHTML(objID,newHTML) {
  var el=document.getElementById(objID);
  el.outerHTML=el.outerHTML.replace(el.innerHTML+'</select>',newHTML+'</select>');
}
person Tyler W. Cox    schedule 27.09.2012

другое решение - использовать Jquery

$('#day').html('<option value="1">1</option><option value="2">2</option>');

person John Adel    schedule 21.10.2014

Я пришел к этому вопросу и хотел поделиться своей проблемой/ответом, надеясь, что это может помочь другим.

У меня было это, что не сработало:

function change_select() {
    var sel = document.getElementById('my-id').innerHTML;
    sel = '<option>new item</option>';
}

Я изменил его на это, которое сработало:

function change_select() {
    var sel = document.getElementById('my-id');
    sel.innerHTML = 'option>new item</option>';
}
person Gavin Palmer    schedule 24.10.2014

Я бы обобщил и резюмировал следующим образом проблему и решение, которое сработало для меня:

Проблема:

Javascript innerHTML больше не работает с выбранными элементами HTML.

Описание:

Стандартный синтаксис Javascript для динамического назначения содержимого HTML (document.getElementById().innerHTML=...) больше не работает с HTML-элементами select, поскольку неизвестна версия (вероятно, все) операционных систем или наиболее часто используемых браузеров; использование его для выбранного элемента приводит к сбою браузера.

Решение:

Чтобы динамически назначить HTML-содержимое HTML-элементу select вместо использования стандартного синтаксиса:

document.getElementById(HTML_select_element_id).innerHTML = <HTML contents to assign>

используйте этот синтаксис:

var select = document.getElementById(HTML_select_element_id);
select.outerHTML = 
    select.outerHTML.replace(
        select.innerHTML
        ,
        <HTML contents to assign>
    )
;
person Luca    schedule 16.06.2016

Как насчет этого:

<div style="display:inline" id=A><select>...</select></div A>

<script>
obj = document.getElementById("A");
newSel = "<select><option>New 1</select>";
obj.innerHTML = newSel;
</script>
person access_granted    schedule 28.01.2016