Короткие и простые: поскольку элементы, которые вы ищете, не существуют в документе (пока).
В оставшуюся часть этого ответа я буду использовать getElementById
как пример, но то же самое относится к getElementsByTagName
, querySelector
и любому другому методу DOM, который выбирает элементы.
Возможные причины
Есть две причины, по которым элемент может не существовать:
getElementById
, действительно соответствует идентификатору существующего элемента в (сгенерированном) HTML и что у вас не было с ошибкой идентификатор (идентификаторы чувствительный !). Кстати, в большинстве современных браузеров , которые реализуют методы querySelector()
и querySelectorAll()
, нотация стиля CSS используется для извлечения элемента его id
, например: document.querySelector('#elementID')
, в отличие от способа, с помощью которого элемент извлекается его id
в [[16]; в первом символе #
необходимо, во втором это приведет к тому, что элемент не будет извлечен. getElementById
]. Последний случай довольно распространен. Браузеры анализируют и обрабатывают HTML сверху вниз. Это означает, что любой вызов элемента DOM, который встречается до появления этого элемента DOM в HTML, не будет выполнен.
Рассмотрим следующий пример:
Появляется div
после script
. В настоящий момент сценарий выполняется, элемент не существует , но и getElementById
вернут null
.
jQuery
То же самое относится к все селекторы с jQuery. jQuery не найдет элементов, если вы ошибочно написали ваш селектор, или вы пытаетесь выбрать их , прежде чем они на самом деле существуют .
Добавленный поворот - это когда jQuery не найден потому, что вы загрузили скрипт без протокола и запускаетесь из файловой системы:
этот синтаксис используется, чтобы позволить сценарию загружаться через HTTPS на странице с протоколом https: // и для загрузки HTTP-версии на странице с протоколом http: //
У этого есть неудачный побочный эффект попытки и невозможность загрузить file://somecdn.somewhere.com...
Решения
Прежде чем позвонить getElementById
(или любой метод DOM, если на то пошло), убедитесь, что элементы, к которым вы хотите получить доступ, существуют, т. е. загружается DOM.
Это может быть обеспечено просто добавив ваш JavaScript после к соответствующему элементу DOM
, и в этом случае вы также можете поместить код непосредственно перед тегом закрывающего тела (
) (все DOM элементы будут доступны в момент выполнения скрипта). [/ g3 6]
Другие решения включают прослушивание событий 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
});
Более подробную информацию об обработке событий и различиях браузера см. в статьях на странице quirksmode.org .
jQuery
Сначала убедитесь, что jQuery загружен правильно , Используйте инструменты разработчика браузера , чтобы узнать, был ли найден файл jQuery и исправлен ли URL-адрес, если он не был (например, добавьте схему http:
или https:
в начале, отрегулируйте путь, и т. д.)
Прослушивание событий load
/ DOMContentLoaded
- это именно то, что делает jQuery с .ready()
[docs] . Весь ваш код jQuery, который влияет на элемент DOM, должен находиться внутри этого обработчика событий.
На самом деле в учебнике j8uery явно указано:
Как почти все, что мы делаем при использовании jQuery, читает или манипулирует объектной моделью документа (DOM), мы должны убедиться, что мы начинаем добавлять события и т. д., как только DOM готов.
Для этого мы регистрируем готовое событие для документа.
blockquote>$(document).ready(function() { // do stuff when DOM is ready });
В качестве альтернативы вы также можете использовать сокращенный синтаксис:
$(function() { // do stuff when DOM is ready });
Оба эквивалентны.
Существует два основных подхода к бизнес-правилам при разработке вашего домена.
1.) Доменные объекты являются базовыми POCO / DTO с. И вы передаете их доменным службам. Эти сервисы могут быть такими же простыми, как другой класс, или они действительно могут быть реальными сервисами, расположенными на другом сервере.
var user = repository.Find(x => x.UserName == userName);
if (userLogonService.IsValidUser(user, password)) {
userLogonService.UpdateUserAsLoggedOn(user);
}
repository.SaveChanges();
2.) Доменные объекты содержат свою собственную логику работы. Это ближе к тому, что последуют многие паттерны MVC. И так как вы спросили, это модель, которую я предпочитаю.
var user = repository.Find(x => x.UserName == userName);
if (user.CheckPassword(password)) {
user.LogOnNow();
}
repository.SaveChanges();
Оба являются полностью действительными шаблонами. # 1 имеет отдельный уровень бизнес-операций, но страдает от модели анемичной области . # 2 может привести к большим объектам домена, если ваш домен начинает усложняться, или если модель может делать много вещей.
Oven.Bake (myPizza) против myPizza.Bake ()
Я в основном согласен. Есть ли у вас единая служба Духовки, или у вас есть десятки доступных печей, которые хранятся в хранилище духовок, где духовка - это просто еще один домен? В # 2 печь является частью домена. То, как я склонен заниматься предметным моделированием, большинство существительных являются предметными сущностями , если только вы не уверены на 100%, что это именно то, что нужно.
Но что-то случается с пиццей, когда она выпекается.
interface ICanBeBaked {
int BakeMinutes { get; }
int BakeTemp { get; }
void Bake();
}
class Pizza : ICanBeBaked {
int BakeMinutes { get { return 15; } }
int BakeTemp { get { return 425; } }
void Bake() {
// melt cheese!
this.isBaked = true;
}
}
class Oven {
void Bake(ICanBeBaked thingToBake) {
// set the temp, reserve this oven for the duration, etc.
thingToBake.Bake();
}
}
Мой "DAL" (больше доморощенный ORM, это другая тема) на самом деле представляет собой пару уровней сам по себе; одна абстракция, которая обеспечивает репозиторий и поддержку некоторых активных шаблонов записи, а ниже - фактический код доступа к данным.
На данный момент у нас есть минимальный бизнес-уровень, но настоящая причина его слабости в том, что в код программной части веб-страницы встроено слишком много (устаревшей) бизнес-логики. По мере того, как это будет переработано, я ожидаю, что бизнес-уровень будет расти, расти и расти.
Это довольно стандартное наслоение. Вы не говорите, почему вы недовольны своим текущим стеком, но имейте в виду, что основная причина для этого - разделение ответственности. Вы также можете ознакомиться с концепциями предметно-ориентированного дизайна; он дает много пищи для размышлений для организации кода вокруг бизнес-политик и практик, а не конкретных проблем программного обеспечения. Это очень полезный аналитический инструмент, который должен быть в вашем наборе инструментов.