Я хочу, чтобы виджет addthis был доступен для моих пользователей, но я хочу лениво загружать его, чтобы загружалась моя страница как можно быстрее. Однако, попробовав его с помощью тега script, а затем с помощью моего метода ленивой загрузки, похоже, он работает только через тег script. В запутанном коде я вижу нечто, похожее на то, что оно зависит от события DOMContentLoaded (по крайней мере, для Firefox).
Поскольку событие DOMContentLoaded уже запущено, виджет не отображается должным образом. Что делать?
Я мог бы просто использовать тег script (медленнее)... или я мог бы запустить (в кросс-браузерном режиме) событие DOMContentLoaded (или эквивалентное)? У меня есть ощущение, что это может быть невозможно, потому что я считаю, что (как и jQuery) существует несколько тестов события готовности контента, и поэтому должно произойти несколько смоделированных событий.
Тем не менее, это интересная проблема, потому что я видел пару виджетов, которые теперь предполагают, что вы включаете их содержимое через статические теги скрипта. Было бы неплохо, если бы они написали код, который был бы более полезен для разработчиков, заботящихся о скорости, но до тех пор есть ли обходной путь? И/или какие-то из моих предположений неверны?
Редактировать: Поскольку первый ответ на вопрос, похоже, упускал суть моей проблемы, я хотел прояснить ситуацию.
Речь идет о конкретной проблеме. Я не ищу еще один сценарий отложенной загрузки или проверяю, загружены ли некоторые зависимости. В частности эта проблема касается
- внешние виджеты, над которыми у вас нет контроля и которые могут быть или не быть запутанными
- задержка загрузки внешних виджетов до тех пор, пока они не потребуются, или, по крайней мере, до тех пор, пока не будет загружено все остальное, включая другие отложенные элементы
- b/c того, как был написан виджет, исключает существующие, типичные парадигмы ленивой загрузки
Хотя это эзотерика, я видел, как это произошло с парой виджетов, где разработчики виджетов предполагают, что вы просто хотите добавить еще один тег сценария внизу страницы. Я хочу сэкономить эти 500-1000 мс**, поскольку многочисленные исследования Yahoo, Google и Amazon показывают, что это важно для вашего пользовательского опыта.
**Мой тест с головкой-молотом и личный опыт показывают, что в данном случае это будет моя экономия.
Ответ 2 · рейтинг 8 · Keith Bentrup
Этот код решает проблему и экономит время загрузки, которое я искал.
Прочитав этот сообщение о том, как большинство современных библиотек js реализуют тесты для события, загруженного домом. Я провел некоторое время с запутанным кодом и смог определить, что addthis использует комбинацию упомянутого метода doscroll, таймеров и события DOMContentLoaded для различных браузеров. Поскольку только тем браузерам, которые зависят от события DOMContentloaded, в любом случае потребуется следующий код:
if( document.createEvent ) {
var evt = document.createEvent("MutationEvents");
evt.initMutationEvent("DOMContentLoaded", true, true, document, "", "", "", 0);
document.dispatchEvent(evt);
}
а остальные зависят от таймеров, проверяющих наличие определенных свойств, мне нужно было только приспособить этот случай, чтобы иметь возможность лениво загружать этот внешний JS-контент, а не использовать статические теги скрипта, тем самым экономя время, на которое я надеялся. :)
Ответ 3 · рейтинг 1 · Jonathan Fingland
Редактировать: если цель состоит в том, чтобы сначала загрузить другой контент, попробуйте поместить теги <script> в нижней части страницы. Он по-прежнему сможет перехватывать DOMContentLoaded, а предшествующий контент будет загружаться перед сценарием.
Оригинал:
в дополнение к загрузке DOMContentLoaded, вы можете загрузить его, если для определенного var установлено значение true. например
var isDOMContentLoaded = false;
document.addEventListener("DOMContentLoaded",function() { isDOMContentLoaded = true; }, false);
затем добавьте в другой файл сценария
if (isDOMContentLoaded) loadThisScript();
Изменить в ответ на комментарии:
Загрузите сценарий и запустите функцию, которую запускает прослушиватель DOMContentLoaded. (прочитайте сценарий, если вы не уверены, какая функция вызывается).
e.g.
var timerID;
var iteration=0;
function checkAndLoad() {
if (typeof loadThisScript != "undefined") {
clearInterval(timerID);
loadThisScript();
}
iteration++;
if (iteration > 59) clearInterval(timerID);
}
var extScript = document.createElement("script");
extScript.setAttribute("src",scriptSrcHere);
document.head.appendChild(extScript);
timerID = setInterval(checkAndLoad,1000);
Вышеописанное будет пытаться раз в секунду в течение 60 секунд проверять, доступна ли нужная вам функция, и, если да, запускать ее