javascript DOMContentLoaded 事件未触发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9722950/
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
DOMContentLoaded event not firing
提问by Gruntcakes
I'm trying to detect when the DOM is ready using DOMContentLoaded.
我正在尝试使用 DOMContentLoaded 检测 DOM 何时准备就绪。
I'm injecting the following JavaScript code into a page:
我将以下 JavaScript 代码注入页面:
var script = document.createElement('script');
script.type = 'text/javascript';
script.text = function addListener() {
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", DOMReady, false);
}
};
function DOMReady() {
document.location.href = "mydomain://anything.stuff";
}
function inject() {
document.getElementsByTagName('head')[0].appendChild(script);
addListener();
}
It gets added by:
它通过以下方式添加:
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
static BOOL injected = NO;
if (!injected)
{
NSBundle *bundle = [NSBundle mainBundle];
NSURL *jsURL = [bundle URLForResource:@"DetectDOMLoaded" withExtension:@"js"];
NSData *jsData = [NSData dataWithContentsOfURL:jsURL];
NSString *jsScriptAsString = [[NSMutableString alloc] initWithData:jsData encoding:NSUTF8StringEncoding];
[self.webView stringByEvaluatingJavaScriptFromString:jsScriptAsString];
[self.webView stringByEvaluatingJavaScriptFromString:@"inject();"];
injected = YES;
}
If I add alert calls I can see that the call to addEventListener is being successfully made. However the function DOMReady() is never called. Any ideas why not?
如果我添加警报调用,我可以看到对 addEventListener 的调用正在成功进行。然而函数 DOMReady() 永远不会被调用。任何想法为什么不呢?
Thanks
谢谢
采纳答案by joern
The reason is that you inject the javascript in the webViewDidFinishLoad:
method. That method is called after the UIWebLoad has loaded the HTML page. Meaning that the DOMContentLoaded
event may already have been fired, before your javascript has been injected.
原因是您在webViewDidFinishLoad:
方法中注入了 javascript 。在 UIWebLoad 加载 HTML 页面后调用该方法。这意味着DOMContentLoaded
在您的 javascript 被注入之前,该事件可能已经被触发。
I see two possiblities how to fix this problem:
我看到如何解决这个问题的两种可能性:
If you have access to the HTML that you are loading into the UIWebView, insert the javascript directly into the HTML. That guarantees that the javascript is already there when
DOMContentLoaded
is being fired.If you don't have access to the HTML, you could call your
DOMReady()
JS function directly from thewebViewDidFinishLoad:
method (like you callinject()
now). The DOM will be fully loaded at that point. The only insecurity with this option is, that the DOM will be fully loaded but might not yet be fully rendered. So if you need the size of certain DOM elements, this option is not secure (because the elements might not have been rendered at that point). But if you are just doing something that does not rely on the DOM being fully rendered, this option should be fine.
如果您有权访问加载到 UIWebView 中的 HTML,请将 javascript 直接插入到 HTML 中。这保证了 javascript 在
DOMContentLoaded
被触发时已经存在。如果您无权访问 HTML,则可以
DOMReady()
直接从该webViewDidFinishLoad:
方法调用您的JS 函数(就像您inject()
现在调用的那样)。DOM 将在此时完全加载。此选项唯一的不安全因素是 DOM 将完全加载但可能尚未完全呈现。因此,如果您需要某些 DOM 元素的大小,则此选项不安全(因为此时元素可能尚未呈现)。但是如果你只是在做一些不依赖于 DOM 被完全渲染的事情,这个选项应该没问题。