检测是否有任何 JavaScript 函数正在运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8790099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect if any JavaScript function is running
提问by gotqn
I know it may sound very strange, but I need to know if there is any active/running javascript in the page.
我知道这听起来可能很奇怪,但我需要知道页面中是否有任何活动/正在运行的 javascript。
I am in situation in which I have to run my javascript/jquery code after everything on the page is rendered and all other scripts have finished.
我的情况是,在呈现页面上的所有内容并且所有其他脚本都完成后,我必须运行我的 javascript/jquery 代码。
Is it possible to detect this?
是否有可能检测到这一点?
EDIT:
编辑:
Thank you all for the answers. Unfortunately, I was not able to find a solution, because I have no full control of what is going on the page.
谢谢大家的回答。不幸的是,我无法找到解决方案,因为我无法完全控制页面上的内容。
Even, I was able to put my javascript in the end of the page, I think it will not be solution again. The reason is that when the page is rendering a function is triggered, it calls other functions and they calls other and so on. As a result, some of the data is incorrect and that's why i need to run my code to correct it.
甚至,我能够将我的 javascript 放在页面的末尾,我认为它不会再次成为解决方案。原因是当页面渲染一个函数被触发时,它调用其他函数,它们调用其他等等。结果,一些数据不正确,这就是为什么我需要运行我的代码来纠正它。
I use setTimeout with 2 seconds to ensure that my code will be executed last, but this is ugly...
我使用 2 秒的 setTimeout 来确保我的代码将最后执行,但这很难看......
So, thank you all, but this is more problem with the system, not the js.
所以,谢谢大家,但这更多是系统问题,而不是js。
回答by T.J. Crowder
JavaScript on web browsers is single-threaded (barring the use of web workers), so if your JavaScript code is running, by definition no other JavaScript code is running.*
Web 浏览器上的 JavaScript 是单线程的(除非使用Web Worker),因此如果您的 JavaScript 代码正在运行,那么根据定义,没有其他 JavaScript 代码正在运行。*
To try to ensure that your script occurs after all other JavaScript on the page has been downloaded and evaluated and after all rendering has occurred, some suggestions:
为了确保您的脚本在页面上的所有其他 JavaScript 下载和评估后以及所有呈现发生后发生,一些建议:
- Put the script tag for your code at the very end of the file.
- Use the
defer
andasync
attributes on the tag (they'll be ignored by browsers that don't support them, but the goal is to make yours the lastas much as we can). - Hook the
window
load
event via a DOM2 style hookup (e.g.,addEventListener
on browsers with standards support, orattachEvent
on older IE versions). - In the
load
event, schedule your code to run after asetTimeout
with a delay of 0ms (it won't really be zero, it'll be slightly longer).
- 将代码的脚本标记放在文件的最后。
- 使用标签上的
defer
和async
属性(它们将被不支持它们的浏览器忽略,但我们的目标是尽可能使您的属性成为最后一个)。 - 勾
window
load
通过DOM2风格联播(例如,事件addEventListener
与标准支持的浏览器,或attachEvent
在旧版本的IE)。 - 在这种情况
load
下,安排您的代码在setTimeout
延迟 0 毫秒后运行(它不会真正为零,它会稍长一些)。
So, the script
tag:
所以,script
标签:
<script async defer src="yourfile.js"></script>
...and yourfile.js
:
...和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
}
})();
That doesn't mean that other code won't have scheduled itself to run later (via setTimeout
, for instance, just like we did above but with a longer timeout), though.
不过,这并不意味着其他代码不会安排自己稍后运行(setTimeout
例如,通过,就像我们上面所做的那样,但超时时间更长)。
So there are some things you can do to try to be last, but I don't believe there's any way to actually guarantee it without having full control of the page and the scripts running on it (I take it from the question that you don't).
因此,您可以做一些事情来尝试保持最后,但我不相信有任何方法可以在没有完全控制页面和在其上运行的脚本的情况下真正保证它(我从您不知道的问题中获取't)。
(* There are some edge cases where the thread can be suspended in one place and then allow other code to run in another place [for instance, when an ajax call completes while an alert
message is being shown, some browsers fire the ajax handler even though another function is waiting on the alert
to be dismissed], but they're edge cases and there's still only one thing actively being done at a time.)
(* 有一些边缘情况,线程可以在一个地方挂起,然后允许其他代码在另一个地方运行[例如,当alert
显示消息时 ajax 调用完成时,一些浏览器会触发 ajax 处理程序,即使另一个功能正在等待alert
被解雇],但它们是边缘情况,并且一次仍然只有一件事正在积极地完成。)
回答by 538ROMEO
Create a loader
创建加载器
Hi, as javaScript can run async functions or calls, I also needed a way to know when the page was in a stable state. For that purpose, I use a tiny loader in each one of my functions:
嗨,由于 javaScript 可以运行异步函数或调用,我还需要一种方法来知道页面何时处于稳定状态。为此,我在每个函数中都使用了一个小加载器:
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 !
}
}
I often couple it with a freezeClic functionto prevent users to interact with the page when there is a script that is still waiting an ajax / async response (and optionnaly display a preloader icon or screen).
我经常将它与freezeClic 函数结合使用,以防止用户在有脚本仍在等待 ajax/async 响应时与页面交互(并且可以选择显示预加载器图标或屏幕)。
回答by jfriend00
There is no definitive way to do this because you can't really know what the latest is that other scripts have scheduled themselves to run. You will have to decide what you want to target.
没有确定的方法来执行此操作,因为您无法真正知道其他脚本已安排自己运行的最新情况。您必须决定要定位的目标。
- You can try to run your script after anything else that may be running when the DOM is loaded.
- You can try to run your script after anything else that may be running when the page is fully loaded (including images).
- 您可以尝试在加载 DOM 时可能正在运行的任何其他内容之后运行您的脚本。
- 您可以尝试在页面完全加载时可能正在运行的任何其他内容(包括图像)之后运行您的脚本。
There is no reliable, cross-browser way to know which of these events, the scripts in the page are using.
没有可靠的、跨浏览器的方式来知道页面中的脚本正在使用这些事件中的哪一个。
In either case, you hook the appropriate event and then use a setTimeout()
to try to run your script after anything else that is watching those events.
在任何一种情况下,您都可以挂钩适当的事件,然后使用 asetTimeout()
尝试在其他任何正在监视这些事件的事件之后运行您的脚本。
So, for example, if you decided to wait until the whole page (including images) was loaded and wanted to try to make your script run after anything else that was waiting for the same event, you would do something like this:
因此,例如,如果您决定等到整个页面(包括图像)加载完毕,并希望在等待同一事件的其他任何内容之后运行您的脚本,您可以执行以下操作:
window.addEventListener("load", function() {
setTimeout(function() {
// put your code here
}, 1);
}, false);
You would have to use attachEvent()
for older versions of IE.
您将不得不使用attachEvent()
旧版本的 IE。
When using this method, you don't have to worry about where your scripts are loaded in the page relative to other scripts in the page since this schedules your script to run at a particular time after a particular event.
使用此方法时,您不必担心相对于页面中的其他脚本,您的脚本在页面中的加载位置,因为这会安排您的脚本在特定事件之后的特定时间运行。