CEF浏览器等待网站满载

时间:2017-03-23 14:16:39

标签: c# chromium-embedded cefsharp

我正在使用CEFsharp浏览器并确定使用LoadingStateChanged事件加载页面,但它会多次触发。

我只需要在页面完全加载后才能触发它,怎么办呢?

private async void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
    if (!e.Browser.IsLoading)
    {
        await Task.Run(async () =>
        {
            await Task.Delay(3000);
        });

        try
        {
            MessageBox.Show("Page has been loaded");
        }
        catch (Exception ex)
        {

        }
    }
}

3 个答案:

答案 0 :(得分:2)

这几天真的很简单。例如,将以下两行代码放在您的Form_Load中:

  browser = new ChromiumWebBrowser();
  (browser).FrameLoadEnd += Browser_FrameLoadEnd;

然后添加所需的方法:

async void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{ // Jumps in here when the page is fully loaded:
    if (e.Frame.IsMain)
    {
        if (e.Url.Contains("whatever you need"))
        {
            // Call a methode or something else.
        }
    }
}

答案 1 :(得分:0)

此事件的多次触发是一个已知问题,并且是Chromium Embedded Framework(CEF)的一部分,而不是cefSharp。

(github cefsharp回复) https://github.com/cefsharp/CefSharp/issues/1844

本文提供了许多处理此类情况的选项, https://codereview.stackexchange.com/questions/62261/one-shot-events-in-c

答案 2 :(得分:0)

对于那些感兴趣的人,我使用以下变通办法。 我会跟踪已发出的请求数,并且仅在有新请求时才执行操作。 就我而言,这似乎很好。但是我可以想象,浏览器实际上仍然可以执行某些操作,有时您需要等待最后一次完成。

using CefSharp;

public class RequestHandler : IRequestHandler
{
    //left all the irrelevant IRequestHandler methods out of this example code, but you'll need to implement them
    public int NrOfCalls { get; set; }
    public bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
    {
        NrOfCalls++;
        return false;
    }
}
public class Handle
{
    private RequestHandler _requestHandler;
    private IWebBrowser _browser;
    private int previousRequestNrWhereLoadingFinished = -1;

    public Handle()
    {
        _requestHandler = new RequestHandler();
        _browser.RequestHandler = _requestHandler;
    }
    private void _browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
    {
        // Check if page has finished loading
        if (!e.IsLoading)
        {
            //sometimes this is called multiple times for one request, we will only do something if it comes from a newer request than the previous action
            if (previousRequestNrWhereLoadingFinished < _requestHandler.NrOfCalls)
            {
                previousRequestNrWhereLoadingFinished = _requestHandler.NrOfCalls;
                ThisMethodWillOnlyBeCalledOncePerRequest();
            }
        }
    }
}