2010-07-13 39 views
8

我一直在研究这个东西,似乎每个人都认为解决方案是检查Web浏览器的ReadyState,直到设置为完成。WebBrowser DocumentCompleted事件发射不止一次

但实际上事件有时被启动,ReadyState设置为完成几次。

我不认为有一个蹩脚的.NET WebBrowser的解决方案,但如果我使用底层的DOM组件,可能会有一个。

唯一的问题是,我不知道如何访问WebBrowser后面的DOM组件来触发DocumentCompleted事件。

回答

33

DocumentCompleted将针对网页中的每一帧进行触发。硬的方法是计算断帧,向您展示如何访问DOM:

private int mFrameCount; 

private void startNavigate(string url) { 
    mFrameCount = 0; 
    webBrowser1.Navigate(url); 
} 

private void DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { 
    mFrameCount += 1; 
    bool done = true; 
    if (webBrowser1.Document != null) { 
    HtmlWindow win = webBrowser1.Document.Window; 
    if (win.Frames.Count > mFrameCount && win.Frames.Count > 0) done = false; 
    } 
    if (done) { 
    Console.WriteLine("Now it is really done"); 
    } 
} 

最简单的方法是检查完成加载的网址:

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
{ 
    if (e.Url.Equals(webBrowser1.Url)) { 
     Console.WriteLine("Now it is really done"); 
    } 
} 
+0

这个答案的简单方法为我做了。即使我正在使用axWebBrowser1控件。我结束了使用以下。如果(e.uRL.Equals(axWebBrowser1.LocationURL)) – IamBatman 2016-08-18 17:33:55

+0

太棒了!非常感谢 – Grcn 2018-01-09 11:17:17

0

如果页面使用Javascript或<meta refresh>重定向到另一个页面,可能会发生这种情况。

如果是这样,没有好的解决方法。

0

我无法找到任何东西这将给予100%的确定性。 提到的示例(e.Url.Equals(webBrowser1.Url))可能适用于简单的WebBrowser.Navigate(url),但在我的情况下,我单击代码中的节点以在现有框架中打开新框架。大多数“导航”和“DocumentCompleted”火灾的次数将是相同的,但并非总是如此。 “isBusy = false”和“ReadyState = Complete”在完成时(至少到目前为止)将始终是这种情况,但当它仍在加载时,它也会有几次有这种状态。计数帧对我来说似乎也没用,在一种情况下,DocumentCompleted被激发了23次,但是,所有帧和子(-sub-sub等)帧总共为14次。

似乎工作的唯一的东西是等待一段时间(1或2秒?),看看是否有任何事情发生(任何事件触发,任何状态改变)。

嗯,我找到了另一个解决方案。通常我们对整个页面不感兴趣,通常我们想要某些元素存在。因此,在每个DocumentCompleted之后,当“isBusy = false”和“ReadyState = Complete”时,如果此元素存在,我们可以搜索DOM。

相关问题