Не могу найти ошибку в следующем коде Javascript? [dубликат]

Вы можете поместить строку, подобную следующей в начале сценария

echo "Starting $0 at time $(date)" >>/var/log/mylog

, затем посмотреть содержимое файла журнала.

368
задан 12 May 2016 в 01:29

5 ответов

Короткие и простые: поскольку элементы, которые вы ищете, не существуют в документе (пока).

В оставшейся части этого ответа я буду использовать getElementById в качестве примера, но то же самое относится к getElementsByTagName, querySelector и любому другому методу DOM, который выбирает элементы.

Короче и просто:

Там являются двумя причинами, по которым элемент может отсутствовать:

Элемент с переданным идентификатором действительно не существует в документе. Вы должны дважды проверить, что идентификатор, который вы передаете getElementById, действительно соответствует идентификатору существующего элемента в (сгенерированном) HTML и что вы не ошибочно написали идентификатор (идентификаторы чувствительны к регистру!). Кстати, в большинстве современных браузеров, которые реализуют методы querySelector() и querySelectorAll(), нотация стиля CSS используется для извлечения элемента по его id, например: document.querySelector('#elementID'), в отличие от метода, с помощью которого элемент извлекается его id в [[16]; в первом символе # необходимо, во втором это приведет к тому, что элемент не будет извлечен. Элемент не существует в тот момент, когда вы вызываете getElementById.

Последний случай довольно распространен. Браузеры анализируют и обрабатывают HTML сверху вниз. Это означает, что любой вызов элемента DOM, который встречается до появления этого элемента DOM в HTML, не будет выполнен.

Рассмотрим следующий пример:

<script>
    var element = document.getElementById('my_element');
</script>

<div id="my_element"></div>

Появляется div В оставшейся части этого ответа я буду использовать getElementById в качестве примера, но то же самое относится к getElementsByTagName, querySelector и любому другому методу DOM, который выбирает элементы. script. В настоящий момент сценарий выполняется, элемент еще не существует, а getElementById вернет null.

jQuery

То же самое относится ко всем селекторам с jQuery. jQuery не найдет элементов, если вы еще ваш селектор или вы пытаетесь выбрать их до их фактического существования.

Добавленный поворот - это когда jQuery не найден, потому что вы загрузили сценарий без протокола и запущен из файловой системы:

<script src="//somecdn.somewhere.com/jquery.min.js"></script>

этот синтаксис используется, чтобы позволить сценарию загружаться через HTTPS на странице с протоколом https: // и загружать версию HTTP на страница с протоколом http: //

У этого есть неудачный побочный эффект попытки и невозможность загрузить file://somecdn.somewhere.com...

jQuery

Прежде чем позвонить getElementById (или любой метод DOM, если на то пошло), убедитесь, что существуют элементы, которые вы хотите получить, т. е. DOM загружен.

Это может быть обеспечено простым помещением вашего JavaScript , прежде чем они на самом деле существуют соответствующий элемент DOM

<div id="my_element"></div>

<script>
    var element = document.getElementById('my_element');
</script>

, и в этом случае вы также можете поместить код непосредственно перед закрывающим тегом тела ( </body>) (все элементы DOM будут доступны в момент написания сценария выполняется [.d39]

Другие решения включают прослушивание событий load [MDN] или DOMContentLoaded [MDN]. В этих случаях не имеет значения, где в документе вы размещаете код JavaScript, вам просто нужно запомнить, чтобы весь обработчик DOM обрабатывался в обработчиках событий.

Пример:

window.onload = function() {
    // process DOM elements here
};

// or

// does not work IE 8 and below
document.addEventListener('DOMContentLoaded', function() {
    // process DOM elements here
});

Для получения дополнительной информации об обработке событий и различиях браузера см. load [MDN] .

jQuery

Сначала убедитесь, что загружен jQuery должным образом. Используйте инструменты разработчика браузера, чтобы узнать, был ли найден файл jQuery и исправлен ли URL-адрес, если это не так (например, добавьте схему http: или https: в начале, отрегулируйте путь и т. Д.)

Прослушивание событий load / DOMContentLoaded - это именно то, что делает jQuery с помощью Используйте инструменты разработчика браузера . Весь ваш код jQuery, который влияет на элемент DOM, должен находиться внутри этого обработчика событий.

На самом деле в учебнике jQuery явно указано:

Как почти все, что мы делаем при использовании jQuery, читает или манипулирует объектной модели документа (DOM), мы должны убедиться, что мы начинаем добавлять события и т. д., как только DOM готов. Для этого мы регистрируем готовое событие для документа.
$(document).ready(function() {
   // do stuff when DOM is ready
});

В качестве альтернативы вы также можете использовать сокращенный синтаксис:

$(function() {
    // do stuff when DOM is ready
});

Оба эквивалентны.

122
ответ дан 15 August 2018 в 16:46
  • 1
    Стоит ли исправлять последний бит о событии ready, чтобы отразить «более новый», предпочтительный синтаксис, или лучше оставить его как есть, чтобы он работал в более старых версиях? – Tieson T. 25 December 2012 в 14:56
  • 2
    Для jQuery стоит ли добавить альтернативу $(window).load() (и, возможно, синтаксические альтернативы $(document).ready(), $(function(){})? Кажется, это связано, но чувствует , слегка касательное к точке, re создание. – David Thomas 25 December 2012 в 14:58
  • 3
    @David: Хорошая точка с .load. Что касается альтернатив синтаксиса, их можно было бы найти в документации, но поскольку ответы должны быть автономными, на самом деле их стоит добавить. Опять же, я почти уверен, что этот конкретный бит о jQuery уже был дан и, вероятно, рассмотрен в других ответах, и ссылки на него могут быть достаточными. – Felix Kling 25 December 2012 в 15:00
  • 4
    @David: Мне нужно пересмотреть: По-видимому, .load устарел: api.jquery.com/load-event . Я не знаю, только ли это для изображений или window. – Felix Kling 25 December 2012 в 15:03
  • 5
    @David: Не стоит беспокоиться :) Даже если вы не уверены, хорошо, что вы упомянули об этом. Я, вероятно, добавлю несколько простых фрагментов кода, чтобы показать использование. Спасибо за ваш вклад! – Felix Kling 25 December 2012 в 15:05

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

Если вы хотите получить элемент в iframe, вы можете узнать, как здесь.

8
ответ дан 15 August 2018 в 16:46

Как отмечал @FelixKling, наиболее вероятным сценарием является то, что узлы, которые вы ищете, еще не существуют.

Однако современные методы разработки часто могут манипулировать элементами документа за пределами дерева документов либо с DocumentFragments, либо просто отсоединением / повторным подключением текущих элементов напрямую. Такие методы могут использоваться как часть шаблонов JavaScript или избегать чрезмерных операций перерисовки / переплавки, в то время как элементы, о которых идет речь, сильно изменены.

Аналогично, новая функциональность «Теневой DOM» развертывается в современных браузерах позволяет элементам быть частью документа, но не обрабатываться запросом document.getElementById и всеми его методами sibling (querySelector и т. д.). Это делается, чтобы инкапсулировать функциональность и, в частности, скрыть ее.

Опять же, скорее всего, элемент, который вы ищете, просто (пока) в документе, и вы должны делать то, что предлагает Феликс , Однако вы также должны знать, что это все больше и больше не единственная причина, по которой элемент может быть неоправданным (временно или постоянно).

8
ответ дан 15 August 2018 в 16:46

Причины, почему селекторы на основе id не работают

Элемент / DOM с указанным идентификатором еще не существует. Элемент существует, но он не зарегистрирован в DOM [в случае добавления HTML-узлов динамически из ответов Ajax]. Существует более одного элемента с одним и тем же идентификатором, который вызывает конфликт.

Причины, по которым селекторы на основе id не работают

Элемент / DOM с указанным идентификатором еще не существует. Для элементов, исходящих из ответов Ajax, используйте метод .bind() jQuery. Более старые версии jQuery для этого были .live(). Элемент существует, но он не зарегистрирован в DOM [в случае добавления HTML-узлов динамически из ответов Ajax].
9
ответ дан 15 August 2018 в 16:46

Попробуйте поместить document.getElementById в setTimeout()

Например:

setTimeout(function(){
    console.log(document.getElementById('whatever'));
}, 100);

Если это работает, тогда это всего лишь проблема синхронизации.

-2
ответ дан 15 August 2018 в 16:46
  • 1
    Это ненадежно. Это не проблема времени. См. Другие ответы здесь для объяснений реальных решений и . – Xufox 10 August 2018 в 17:05

Другие вопросы по тегам:

Похожие вопросы: