Как постараться не переопределять ВЕРСИЮ, ПАКЕТ, и т.д.

Элемент, который вы пытались найти, не был в DOM , когда ваш скрипт работал.

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

Рассмотрим следующую разметку; сценарий # 1 не находит

, а сценарий # 2 преуспевает:


test div

Итак, что вы должны делать? У вас есть несколько вариантов:


Вариант 1: Переместите свой скрипт

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


  
  

Примечание: размещение скриптов внизу как правило, считается лучшей практикой .


Вариант 2: jQuery's ready()

Отмените свой сценарий до тех пор, пока DOM не будет полностью проанализирован, используя ready() :



Примечание. Вы можете просто привязать к DOMContentLoaded или window.onload, но у каждого есть свои оговорки. jQuery ready() предоставляет гибридное решение.


Вариант 3: Делегирование событий

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

blockquote>

Когда элемент вызывает событие (при условии, что это bubbling g6], и ничто не останавливает его распространение), каждый родитель в родословной этого элемента также получает событие. Это позволяет нам привязать обработчик к существующему элементу и примерным событиям, когда они пузырятся от его потомков ... даже те, которые добавлены после присоединения обработчика. Все, что нам нужно сделать, это проверить событие, чтобы узнать, был ли он поднят нужным элементом и, если да, запустите наш код.

jQuery on() выполняет эту логику для нас. Мы просто предоставляем имя события, селектор для желаемого потомка и обработчик событий:



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


Вариант 4: Атрибут defer

Используйте атрибут defer в

Для справки, вот код из этого внешнего скрипта :

document.getElementById("test").addEventListener("click", function(e){
   console.log("clicked: %o", this); 
});

Примечание: атрибут defer, безусловно, кажется , как волшебная пуля , но важно знать об оговорках ... 1. defer может использоваться только для внешних скриптов, т. е. для тех, у кого есть атрибут src. 2. знать о поддержке браузера , то есть: ошибка реализации в IE & lt; 10

9
задан Willem Van Onsem 8 October 2015 в 01:10
поделиться

3 ответа

Некоторые примечания:

  • Вы не упоминали как config.h был включен - с кавычками или угловыми скобками. Посмотрите этот другой вопрос для получения дополнительной информации о различии. Короче говоря, config.h обычно включается с кавычками, не угловыми скобками, и это должно заставить препроцессор предпочесть config.h из собственного каталога проекта (который обычно является, что Вы хотите),
  • Вы говорите, что подпроект должен включать проект включения config.h Обычно это нисколько не, что Вы хотите. Подпроект автономен, и его ПАКЕТ, и ВЕРСИЯ должна быть той того подпроекта, не Вашего. При включении libxml в xmlreader проект, например, Вы все еще хотели бы, чтобы код libxml был скомпилирован с ПАКЕТОМ libxml и ВЕРСИЕЙ (независимо от того, что libxml версия).
  • Это обычно - большая ошибка иметь config.h будьте включены от общедоступных заголовков. config.h является всегда частным к Вашему проекту или подпроекту, и должен только быть включен из.c файлов. Так, если в документации Вашего поставщика говорится для включения их "vendor.h" и что общедоступный заголовок включает config.h так или иначе затем это нет - нет. Точно так же, если Ваш проект является библиотекой, не включать config.h где угодно от Ваших публично установленных заголовков.
5
ответ дан 4 December 2019 в 22:31
поделиться

Это - определенно взлом, но я выполняю последующую обработку autogen'd config.h файл:

sed -e 's/.*PACKAGE_.*//' < config.h > config.h.sed && mv config.h.sed config.h

Это терпимо в нашей среде сборки, но мне было бы интересно более чистым способом.

2
ответ дан 4 December 2019 в 22:31
поделиться

Это поворачивается, там было очень простое решение в моем случае. Проект поставщика собирает несколько заголовочных файлов в один монолитный заголовочный файл, который является затем #included по источникам поставщика. Но сделать правило, которое создает монолитный заголовок случайно, включало сгенерированный config.h. Присутствие ПАКЕТА, ВЕРСИИ, и т.д. конфигурируется, переменные в монолитном заголовке то, что вызывало предупреждения переопределения. Оказывается что поставщик config.h было не важно, потому что "config.h", всегда разрешаемый к $(top_builddir)/config.h.

Я полагаю, что это - способ, которым это, как предполагается, работает. По умолчанию подпроект должен включать проект включения config.h вместо его собственного, если подпроект явно не включает свое собственное, или управляет ВКЛЮЧАТЬ путем так, чтобы его собственный каталог появился прежде $(top_builddir), или иначе управляет заголовочными файлами как в моем случае.

1
ответ дан 4 December 2019 в 22:31
поделиться
Другие вопросы по тегам:

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