«Предупреждает ли кто-нибудь, как работает в пользу document.ready?»
Конечно. Но не в пользу document.ready, а в пользу «динамически загружаемых данных таблицы .ready».
Смотрите ваш второй фрагмент кода:
Сначала вы вызываете populateTableData (): я рассчитываю асинхронно прочитать данные, вероятно, с удаленного сервера через Ajax-запрос.
И затем вы вызываете toggleHintText () для реализации эффекта переключения над строками таблицы, и я выясняю, что некоторый обратный вызов, реализованный внутри populateTableData (), будет добавляться, как только завершится запрос Ajax (или аналогичная асинхронная операция).
Javascript является однопоточным (что означает, что ваш код выполняется в одном потоке и, следовательно, не содержит параллелизма), но не полностью свободен от параллелизма, поскольку асинхронные операции сопровождаются другими параллельные потоки, работающие или ожидающие завершения необходимых операций, а затем (инициированное событие завершения) помещают задачу в цикл основных задач javascript (обработчик событий, присоединенный к этому элементу).
Вызов alert () останавливает выполнение основного цикла javascript, но не параллельные потоки, посещающие асинхронные задачи.
Таким образом, он может успешно завершить операцию запроса Ajax (даже без сбоя тайм-аута сервера из-за «паузы оповещения») и вызвать событие завершения.
... Но обратный вызов, прикрепленный к этому событию, не будет выполнен, пока не продолжится цикл задач javascript.
Ваша функция toggleHintText () вызывается SURE до того, как данные вашей таблицы заполнены, и без оповещения () остальная часть ее кода НЕ найдет никаких элементов в этой таблице (или, по крайней мере, новых элементов, заполненных populateTableData ()). ).
Таким образом, существует причина, по которой без предупреждения () ваш код не работает.
Но я не уверен, почему это работает даже с предупреждением. Я выяснил, что ваш браузер может реализовать остановку оповещения как «paused nextTick ()» и выполнить, по крайней мере, ожидающие обработчики событий, как можно скорее (но я думаю, что это не совсем правильно в спецификации javascript).
Чтобы избежать этой проблемы, необходимо вызвать toggleHintText (), когда вы уверены , что данные заполнены в таблице. То есть:
Вызовите его из обработчика событий, который заполняет данные о (предполагаемом) завершении запроса Ajax.
Запустите свой собственный элемент в этот момент и прикрепите toggleHint () в качестве его обработчика события.
Также можно изменить обработчики событий toggleHintText (), которые будут присоединены к самим таблицам (или ко всему документу), а не к более поздним динамически загружаемым элементам, а затем проверить цель события.
Это то, что сделал устаревший метод .live () jquery и что в настоящее время может быть достигнуто просто с помощью .on () и целевого селектора. Например:
В вашем коде:
var searchField = $('input:text');
...
searchField.focus(function() {...});
... последняя строка эквивалентна:
searchField.on("focus", function(){});
Вы можете заменить его (например) на:
$("body").on("focus", 'input:text', function(){...});
Таким образом, обработчик событий присоединяется непосредственно к телу документа, и при каждом событии фокуса он будет проверять, соответствует ли цель указанному селектору (независимо от того, был ли элемент создан перед вложением обработчика событий или нет).
В итоге: вы не можете прикрепить обработчик событий к элементу, который еще не существует.
С другой стороны, у вас есть некоторые элементы управления, такие как добавление классов и атрибутов. Вы не можете сделать это до создания элемента, но, аналогично, вы можете прикрепить обработчик события к его событию "creation".
Но, к сожалению, этого события на самом деле не существует. Но есть методы, чтобы реализовать это через событие dom change. См. этот вопрос о плагине liveQuery.