Почему document.getElementById () возвращает нулевое значение, когда я знаю, что идентификатор существует? - PullRequest
2 голосов
/ 29 сентября 2010

Я работаю над некоторым пользовательским Javascript для шаблона CMS на работе.Я хочу, чтобы определенный элемент <li> на странице получал класс "current" только для этой страницы.Таким образом, в заголовке глобальной страницы у меня есть что-то вроде этого:

<script type="text/javascript">
    function makeCurrent(id) {
      var current = document.getElementById(id);
      current.setAttribute("class", "current"); // for most browsers
      current.setAttribute("className", "current"); // for ie
    }
</script>

Затем на каждой отдельной странице <head>, у меня есть что-то вроде этого:

<script type="text/javascript">makeCurrent("undergraduate")</script>

На странице у меня естьnav <ul>, с чем-то вроде:

<li id="undergraduate"><a href="...">Undergraduate Program</a></li>
<li id="graduate"><a href="...">Graduate Program</a></li>

etc.

Когда я загружаю страницу, класс не применяется.Когда я смотрю в консоль Firebug, она выдает сообщение об ошибке:

current is null
(x)  current.setAttribute("class", "current"); 

Я все еще получаю навык написания твердого, сырого javascript (изучая в обратном порядке после jQuery, вы знаете, как это происходит), ноЯ хочу написать это только на JS.Какую идиотскую ошибку новичка я делаю?

Спасибо всем!

Ответы [ 5 ]

3 голосов
/ 29 сентября 2010

Если вы выполните javascript до того, как дерево DOM завершит загрузку, оно вернет ноль. Таким образом, идея состоит в том, чтобы вызвать функцию полностью в конце, прежде чем закрыть тег body.

Именно поэтому большинство библиотек JavaScript поддерживают событие, готовое к dom, современные браузеры также имеют это (domcontentloaded), однако для широкой поддержки браузеров сделать это немного сложнее для себя (ну, не так сложно, 4 разных способа я думаю.)

2 голосов
/ 29 сентября 2010

DOM загружен не полностью, если вы запускаете makeCurrent в своей голове. Вы должны поместить этот скрипт после ваших <li> тегов.

Ваш код может быть оптимизирован: вы можете установить атрибут class напрямую с помощью current.className = 'current';.

2 голосов
/ 29 сентября 2010

Элемент еще не существует , когда этот скрипт проверяется. Поместите его в обработчик загрузки тела или что-то в этом роде, чтобы он выполнялся, когда DOM установлен.

Пример того, как это сделать, не касаясь разметки:

function callWhenLoaded(func) {
  if (window.addEventListener) {
    window.addEventListener("load", func, false);
  } else if (window.attachEvent) {
    window.attachEvent("onload", func);
  }
}

callWhenLoaded(function() { makeCurrent("undergraduate"); });
1 голос
/ 29 сентября 2010

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

  • Опечатка в личности
  • Идентификация - это не то, о чем вы думаете, потому что она создается или частично генерируется веб-фреймворком, который вы используете, т.е. в ASP.NET вы можете установить идентификатор клиента в «MyControl» только для того, чтобы найти его к тому времени он отображается в клиенте как «Page_1 $ Control_0 $ MyControl $ 1»
  • Вы добавили, например, знак # в одном или нескольких неправильных местах, хотя вы не используете jQuery в своем примере, если идентификатор объекта - MyControl, в jQuery и CSS вы ссылаетесь на него с помощью #MyControl , но в фактическом id объекта вы не использовали #. В document.getElementById () вы не используете #, как вы бы использовали в jQuery и CSS, но вы могли использовать его непреднамеренно.
  • Вы установили элемент name в элементе управления вместо идентификатора.

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

1 голос
/ 29 сентября 2010

Причина в том, что ваш скрипт запускается до завершения загрузки страницы, и, следовательно, до заполнения DOM.

Вам нужно убедиться, что вы вызываете функцию только после завершения загрузки страницы.Сделайте это, вызвав его с помощью document.onload () или события onload для тега body.

...