7

我试图找出这是否可能。我已经浏览了 GitHub 示例https://github.com/chillitom/CefSharp,它为我提供了类的源代码(尽管我无法从这个 GITHUB 构建 CefSharp 本身。

但是,我确实尝试了从此链接https://github.com/downloads/ataranto/CefSharp/CefSharp-1.19.0.7z下载二进制文件,然后通过引用这些示例构建了我的 C# win32 应用程序,这相当顺利,之后8 小时左右,我有了一个可以工作的嵌入式浏览器,yipeee。但是,我现在正处于要操作 DOM 的地步——我已经读到您只能使用 webView.EvaluateScript("some script"); 和 webView.ExecuteScript("一些脚本"); 因为无法通过 cefsharp 直接访问 DOM

所以我想知道的是。我可以调用 jQuery 方法吗?如果我加载的页面已经加载了jQuery,我可以在c#中执行以下操作吗?

webView.ExecuteScript("$(\"input#some_id\").val(\"user@example.com\")"));

目前这会引发异常。我试图找出答案;我什至应该尝试使用 cefsharp DLL 中的 jQuery,还是我必须坚持使用标准的老式 JavaScript,这将花费我 5 倍的时间来编写......?

我希望堆垛机会有答案。我已经尝试过 cefsharp 的 wiki 和论坛,但它们提供的线索不多;我发现的唯一例子是老式的 JavaScript。

4

2 回答 2

6

是的,您可以使用 jQuery,但是您只能在 DOM 完全加载后才能使用它。为此,您需要使用 WebView 的 PropertyChanged 事件来检查 IsLoading 属性何时更改为 false 并且 IsBrowserInitialized 属性设置为 true。

请参阅下面的片段,了解我如何在我的一个项目中做到这一点。正如你所看到的,一旦 IsLoading 属性发生变化,我就会调用一些方法来设置 WebView 中的内容,这是通过 ExecuteScript 调用 jQuery 来完成的。

/// <summary>
/// Initialise the WebView control
/// </summary>
private void InitialiseWebView()
{
    // Disable caching.
    BrowserSettings settings = new BrowserSettings();
    settings.ApplicationCacheDisabled = true;
    settings.PageCacheDisabled = true;

    // Initialise the WebView.
    this.webView = new WebView(string.Empty, settings);
    this.WebView.Name = string.Format("{0}WebBrowser", this.Name);
    this.WebView.Dock = DockStyle.Fill;

    // Setup and regsiter the marshal for the WebView.
    this.chromiumMarshal = new ChromiumMarshal(new Action(() => { this.FlushQueuedMessages(); this.initialising = false; }));
    this.WebView.RegisterJsObject("marshal", this.chromiumMarshal);

    // Setup the event handlers for the WebView.
    this.WebView.PropertyChanged += this.WebView_PropertyChanged;
    this.WebView.PreviewKeyDown += new PreviewKeyDownEventHandler(this.WebView_PreviewKeyDown);

    this.Controls.Add(this.WebView);
}

/// <summary>
/// Handles the PropertyChanged event of CefSharp.WinForms.WebView.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event arguments.</param>
private void WebView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    // Once the browser is initialised, load the HTML for the tab.
    if (!this.webViewIsReady)
    {
        if (e.PropertyName.Equals("IsBrowserInitialized", StringComparison.OrdinalIgnoreCase))
        {
            this.webViewIsReady = this.WebView.IsBrowserInitialized;
            if (this.webViewIsReady)
            {
                string resourceName = "Yaircc.UI.default.htm";
                using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                {
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        this.WebView.LoadHtml(reader.ReadToEnd());
                    }
                }
            }
        }
    }

    // Once the HTML has finished loading, begin loading the initial content.
    if (e.PropertyName.Equals("IsLoading", StringComparison.OrdinalIgnoreCase))
    {
        if (!this.WebView.IsLoading)
        {
            this.SetSplashText();
            if (this.type == IRCTabType.Console)
            {
                this.SetupConsoleContent();
            }

            GlobalSettings settings = GlobalSettings.Instance;
            this.LoadTheme(settings.ThemeFileName);

            if (this.webViewInitialised != null)
            {
                this.webViewInitialised.Invoke();
            }
        }
    }
}
于 2013-02-19T20:25:09.220 回答
1

您在评论中更清楚地表明您想要做的是将 jQuery 加载到还没有它的页面中。int0x90 关于ExecuteScript在 jQuery 源的本地副本上运行的建议可能对您有用。不过我想提醒您,许多页面与他们的作者从未放在那里的所有额外 JS 不兼容。谷歌和 Facebook 是两个重要的例子。这两个都定义了一个$不是 jQuery 的运算符$,所以踩它几乎肯定会破坏它们。

底层 CEF 库公开了很多从 C++ 直接操作 DOM 元素的方法,CefSharp 没有公开这些方法,因为对它们的需求还不是很大。不过,这听起来确实是您想要在这里使用的。如果您查看 CefSharp 源代码,公开它们可能不会做太多工作,但我自己还没有尝试过。如果您想尝试,也可以将问题发布到https://groups.google.com/forum/#!forum/cefsharp

于 2013-02-21T19:41:45.630 回答