Ошибка в Javascript

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

Конечно, я в javascript не силен. Но логика вроде понятна. Объясните, почему скрипт у меня не работает?

<html>  
    <head>  
        <title>Тестовый шаблон</title>  
        <meta name="description" content="Тестовое описание сайта">  
        <meta name="kyewords" content="описание ключ, ключ, разные ключи которые встречаются на странице">  
        <meta charset="utf-8">  
                <script type="text/javascript">  
            function trargets(){  
            var first = document.getElementById('sity_dan'),  
                second = document.getElementById('sity');  
            first.onchange = second.onchange = function(e) {  
             e = e || window.event;  
             var target = e.target || e.srcElement;  
                 var related = target === first ? second : first;  
             related.selectedIndex = target.selectedIndex;  
                 var x = target.options[target.selectedIndex].text;  
         document.getElementById('sity_name').innerHTML = x;  
        }  
    };  
        </script>  
    </head>  
    <body>      
<p id="sity_name"></p>  
<select id="sity_dan">  
<option selected disabled>Выбрать город</option>  
<option value="Москва">Москва</option>  
<option value="Сочи">Сочи</option>  
<option value="Санкт-Петербург">Санкт-Петербург</option>  
</select>  
</div>

<form name="contact_form" method="post" action="submit.php">  
<select id="sity" name="sity" placeholder="Выбрать город">  
  <option selected disabled>Выбрать город</option>  
  <option value="Москва">Москва</option>  
  <option value="Сочи">Сочи</option>  
  <option value="Санкт-Петербург">Санкт-Петербург</option>  
</select>  
<select id="filial" name="filials" placeholder="Выбрать филиал">  
  <option selected disabled>Выбрать филиал</option>  
  <option value="Филиал №1">Филиал №1</option>  
  <option value="Филиал №2">Филиал №2</option>  
  <option value="Филиал №3">Филиал №3</option>  
</select>       
<input id="name" type="text" name="name_order" placeholder="Имя" value="" title="Введите Ваше имя"/>  
<input id="tel" type="text" name="phone"  placeholder="Телефон" value="" title="Номер телефона Ваше имя"/>  
<input type="checkbox" checked="checked" id="check" checked />  
<span id="license">Я принимаю <a href="#">пользовательское соглашение</a></span>  
<input id="but_call" class="red_button" name="send" type="submit" value="Получить!"  />  
    </body>  
</html>

Обновление

Суть вот в чем: есть два селекта, которые друг с другом связаны. Когда мы выбираем город из любого селекта, он его выводит и в первом, и во втором селекте:

related.selectedIndex = target.selectedIndex;

Дальше результат выводится в тег <p>, где отображается название города:

var x = target.options[target.selectedIndex].text;  
document.getElementById('sity_name').innerHTML = x;

Проблема в том, что у меня есть рабочий вариант скрипта. Но мне все это дело нужно как-то обернуть функцию, и я не знаю как!

Ответы

▲ 1Принят

Наверное, вам нужно обернуть в анонимную ф-ю, которая тут же и выполнится:

(function(){
    // здесь весь код
})();

Вот фиддл с вашим кодом в таком варианте. Вроде, работает – города подставляет.

▲ 2

В представленном DOM нет узла с id="sity_dan" => переменная first будет null => это будет вызывать ошибку доступа к члену onchange «недообъекта» first.

Кроме того, вся эта функция будет выполняться непосредственно перед отправкой формы — устанавливать обработчик события onchage в этот момент времени не имеет смысла при описанных условиях.

Отсутствует также узел с id="sity_name" — значит, что строка

document.getElementById('sity_name').innerHTML = x;

тоже будет приводить к ошибке.

А еще _c_ity, а не _s_ity.

Все это я понял только благодаря сверхспособности, на которую обычно не стоит рассчитывать, так что замечание и вопрос тов. @eicto актуальны (особенно вопрос).

UPD

Теперь, когда разметка поправлена и все элементы на месте, осталось только убрать onsubmit="trargets();" за ненадобностью, переместить код в место, где узлы уже будут существовать (или повесить на событие domready) и вызвать функцию:

...
<span id="license">Я принимаю <a href="#">пользовательское соглашение</a></span>
<input id="but_call" class="red_button" name="send" type="submit" value="Получить!" />

<script type="text/javascript">
(function trargets(){
var first = document.getElementById('sity_dan'),
second = document.getElementById('sity');
first.onchange = second.onchange = function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
var related = target === first ? second : first;
related.selectedIndex = target.selectedIndex;
var x = target.options[target.selectedIndex].text;
document.getElementById('sity_name').innerHTML = x;
}
})();
</script>
...
▲ 1

После полуночных измышлений все-таки пришел я к тому, что нужно мне! Спасибо @Sergiks и @Bars, я все-таки смог собрать нужную мне конструкцию. Выкладываю скрипт, который был мне нужен:

function targets() {
    var first = document.getElementById('sity_dan'),
    second = document.getElementById('sity');
    first.onchange = second.onchange = function (e) {
        e = e || window.event;
        var target = e.target || e.srcElement;
        var related = target === first ? second : first;
        related.selectedIndex = target.selectedIndex;
        var x = target.options[target.selectedIndex].text;
        document.getElementById('sity_name').innerHTML = x;
    }
};
document.addEventListener( "DOMContentLoaded", targets, false );

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

"повесить на событие domready и вызвать функцию"