Skip to content Skip to sidebar Skip to footer

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' i

Solution 1:

Here's how I solved the problem in my application:

privatevoidwbPost_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (e.Url != wbPost.Url)
        return;
    /* Document now loaded */
}

Solution 2:

My approach to doing something when page is completely loaded (including frames) is something like this:

using System.Windows.Forms;
    protecteddelegatevoidProcedure();
    privatevoidexecuteAfterLoadingComplete(Procedure doNext) {
        WebBrowserDocumentCompletedEventHandler handler = null;
        handler = delegate(object o, WebBrowserDocumentCompletedEventArgs e)
        {
            ie.DocumentCompleted -= handler;
            Timer timer = new Timer();
            EventHandler checker = delegate(object o1, EventArgs e1)
            {
                if (WebBrowserReadyState.Complete == ie.ReadyState)
                {
                    timer.Dispose();
                    doNext();
                }
            };
            timer.Tick += checker;
            timer.Interval = 200;
            timer.Start();
        };
        ie.DocumentCompleted += handler;
    }

From my other approaches I learned some "don't"-s:

  • don't try to bend the spoon ... ;-)
  • don't try to build elaborate construct using DocumentComplete, Frames, HtmlWindow.Load events. Your solution will be fragile if working at all.
  • don't use System.Timers.Timer instead of Windows.Forms.Timer, strange errors will begin to occur in strange places if you do, due to timer running on different thread that the rest of your app.
  • don't use just Timer without DocumentComplete because it may fire before your page even begins to load and will execute your code prematurely.

Solution 3:

Here's my tested version. Just make this your DocumentCompleted Event Handler and place the code that you only want be called once into the method OnWebpageReallyLoaded(). Effectively, this approach determines when the page has been stable for 200ms and then does its thing.

// event handler for when a document (or frame) has completed its downloadTimer m_pageHasntChangedTimer = null;
privatevoidwebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e ) {
    // dynamic pages will often be loaded in parts e.g. multiple frames// need to check the page has remained static for a while before safely saying it is 'loaded'// use a timer to do this// destroy the old timer if it existsif ( m_pageHasntChangedTimer != null ) {
        m_pageHasntChangedTimer.Dispose();
    }

    // create a new timer which calls the 'OnWebpageReallyLoaded' method after 200ms// if additional frame or content is downloads in the meantime, this timer will be destroyed// and the process repeated
    m_pageHasntChangedTimer = newTimer();
    EventHandler checker = delegate(object o1, EventArgs e1 ) {
        // only if the page has been stable for 200ms already// check the official browser state flag, (euphemistically called) 'Ready'// and call our 'OnWebpageReallyLoaded' methodif ( WebBrowserReadyState.Complete == webBrowser.ReadyState ) {
            m_pageHasntChangedTimer.Dispose();
            OnWebpageReallyLoaded();
        }
    };
    m_pageHasntChangedTimer.Tick += checker;
    m_pageHasntChangedTimer.Interval = 200;
    m_pageHasntChangedTimer.Start();
}

OnWebpageReallyLoaded() {
    /* place your harvester code here */
}

Solution 4:

How about using javascript in each frame to set a flag when the frame is complete, and then have C# look at the flags?

Solution 5:

I'm not sure it'll work but try to add a JavaScript "onload" event on your frameset like that :

functioneverythingIsLoaded() { alert("everything is loaded"); }
var frameset = document.getElementById("idOfYourFrameset");
if (frameset.addEventListener)
    frameset.addEventListener('load',everythingIsLoaded,false); 
else
    frameset.attachEvent('onload',everythingIsLoaded); 

Post a Comment for "Html - How Do I Know When All Frames Are Loaded?"