Search code examples
c#htmlbrowsermshtml

HTML - How do I know when all frames are loaded?


I'm using .NET WebBrowser control. How do I know when a web page is fully loaded?

I want to know when the browser is not fetching any more data. (The moment when IE writes 'Done' in its status bar...).

Notes:

  • The DocumentComplete/NavigateComplete events might occur multiple times for a web site containing multiple frames.
  • The browser ready state doesn't solve the problem either.
  • I have tried checking the number of frames in the frame collection and then count the number of times I get DocumentComplete event but this doesn't work either.
  • this.WebBrowser.IsBusy doesn't work either. It is always 'false' when checking it in the Document Complete handler.

Solution

  • Here's what finally worked for me:

           public bool WebPageLoaded
        {
            get
            {
                if (this.WebBrowser.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)
                    return false;
    
                if (this.HtmlDomDocument == null)
                    return false;
    
                // iterate over all the Html elements. Find all frame elements and check their ready state
                foreach (IHTMLDOMNode node in this.HtmlDomDocument.all)
                {
                    IHTMLFrameBase2 frame = node as IHTMLFrameBase2;
                    if (frame != null)
                    {
                        if (!frame.readyState.Equals("complete", StringComparison.OrdinalIgnoreCase))
                            return false;
    
                    }
                }
    
                Debug.Print(this.Name + " - I think it's loaded");
                return true;
            }
        }
    

    On each document complete event I run over all the html element and check all frames available (I know it can be optimized). For each frame I check its ready state. It's pretty reliable but just like jeffamaphone said I have already seen sites that triggered some internal refreshes. But the above code satisfies my needs.

    Edit: every frame can contain frames within it so I think this code should be updated to recursively check the state of every frame.