Обнаруживать, работает ли какая-либо функция JavaScript
Я знаю, это может показаться очень странным, но мне нужно знать, есть ли какой-либо активный/запущенный javascript на странице.
Я в ситуации, когда мне нужно запустить свой javascript/jquery-код после того, как все на странице будет показано, и все остальные скрипты закончены.
Можно ли это обнаружить?
EDIT:
Спасибо всем за ответы. К сожалению, я не смог найти решение, потому что у меня нет полного контроля над тем, что происходит на странице.
Даже, я смог поместить свой javascript в конце страницы, я думаю, что это не будет решением снова. Причина в том, что когда страница выполняет рендеринг функции, она вызывает другие функции и вызывает другие и т.д. В результате некоторые данные неверны и поэтому мне нужно запустить свой код, чтобы исправить его.
Я использую setTimeout с 2 секундами, чтобы гарантировать, что мой код будет выполнен последним, но это уродливо...
Итак, спасибо вам, но это больше проблема с системой, а не с js.
Ответы
Ответ 1
JavaScript в веб-браузерах является однопоточным (запрет на использование веб-работников), поэтому, если ваш код JavaScript запущен, по определению нет другой код JavaScript работает. *
Чтобы убедиться, что ваш script происходит после того, как все остальные JavaScript на странице были загружены и оценены, и после всего рендеринга некоторые предложения:
- Поместите тег script для вашего кода в самом конце файла.
- Используйте теги
defer
и async
в теге (они будут игнорироваться браузерами, которые их не поддерживают, но цель состоит в том, чтобы сделать вашу последнюю как можно больше).
- Захватите событие
window
load
с помощью подключения стиля DOM2 (например, addEventListener
в браузерах с поддержкой стандартов или attachEvent
в старых версиях IE).
- В событии
load
планируйте свой код для запуска после setTimeout
с задержкой 0 мс (он не будет действительно нулевым, он будет немного длиннее).
Итак, тег script
:
<script async defer src="yourfile.js"></script>
... и yourfile.js
:
(function() {
if (window.addEventListener) {
window.addEventListener("load", loadHandler, false);
}
else if (window.attachEvent) {
window.attachEvent("onload", loadHandler);
}
else {
window.onload = loadHandler; // Or you may want to leave this off and just not support REALLY old browsers
}
function loadHandler() {
setTimeout(doMyStuff, 0);
}
function doMyStuff() {
// Your stuff here. All images in the original markup are guaranteed
// to have been loaded (or failed) by the `load` event, and you know
// that other handlers for the `load` event have now been fired since
// we yielded back from our `load` handler
}
})();
Это не означает, что другой код не будет иметь запланированный запуск позже (через setTimeout
, например, так же, как мы делали выше, но с более длинным таймаутом).
Итак, есть некоторые вещи, которые вы можете сделать, чтобы попытаться быть последними, но я не верю, что существует какой-либо способ гарантировать это, не имея полного контроля над страницей и сценариями, запущенными на ней (я беру это из вопроса что вы этого не делаете).
(* Есть несколько случаев, когда поток можно приостановить в одном месте, а затем разрешить запуск другого кода в другом месте [например, когда вызов ajax завершается, пока отображается сообщение alert
, некоторые браузеры пожар обработчика ajax, даже если другая функция ожидает отклонения alert
], но они являются краевыми случаями, и одновременно выполняется только одна вещь.)
Ответ 2
Создать загрузчик
Привет, извините за поздний ответ. Мой способ справиться с этим - маленький загрузчик, который я активирую или нет
Я нашел решение:
var loading_var = 0;
// some functions in your code that may not execute at the same time
// or have to wait an async call
function f1() {
loading_var++;
// code to be exectuted
onready();
}
function f2() {
loading_var++;
// code to be exectuted
onready();
}
// loader function
function onready() {
loading_var--;
if(loading_var == 0) {
// Means all functions have finished executing !
}
}
Я часто связываю это с функцией freezeClic, чтобы пользователи не могли взаимодействовать со страницей, когда есть сценарий, который все еще ожидает ответ ajax/async (и, возможно, отображает значок или экран предварительного загрузчика).
Ответ 3
Нет никакого определенного способа сделать это, потому что вы не можете действительно знать, что последнее - это то, что другие сценарии планировали запустить. Вам нужно будет решить, на что вы хотите нацелиться.
- Вы можете попробовать запустить script после всего, что может быть запущено при загрузке DOM.
- Вы можете попробовать запустить script после всего, что может быть запущено, когда страница полностью загружена (включая изображения).
Нет надежного кросс-браузерного способа узнать, какие из этих событий используются сценарии на странице.
В любом случае вы подключаете соответствующее событие, а затем используйте setTimeout()
, чтобы попытаться запустить script после всего, что просматривает эти события.
Итак, например, если вы решили дождаться загрузки всей страницы (включая изображения) и попытались сделать ваш script запуск после чего-то еще, ожидающего того же события, вы бы сделали что-то вроде это:
window.addEventListener("load", function() {
setTimeout(function() {
// put your code here
}, 1);
}, false);
Вам понадобится использовать attachEvent()
для более старых версий IE.
При использовании этого метода вам не нужно беспокоиться о том, где ваши скрипты загружаются на страницу по сравнению с другими сценариями на странице, так как это позволяет вашему script запускаться в определенное время после определенного события.