我已成功将CefSharp嵌入到.NET 4.0应用程序中。是否有可能使jQuery调用在DOM上起作用?

7
我想知道是否有可能实现这一点。我已经查看了GitHub示例https://github.com/chillitom/CefSharp,这为我提供了类的源代码(尽管我无法从这个GITHUB构建CefSharp本身)。
然后,我尝试了来自此链接https://github.com/downloads/ataranto/CefSharp/CefSharp-1.19.0.7z的二进制文件下载,并通过引用这些示例构建了我的C# win32应用程序,这相当顺利。8小时左右后,我得到了一个可以工作的嵌入式浏览器,太棒了。但是,我现在想要操作DOM——我已经读到你只能使用webView.EvaluateScript("some script"); 和 webView.ExecuteScript("some script"); 进行操作,因为cefsharp不支持直接访问DOM。
所以我想知道的是:我可以调用jQuery方法吗?如果我加载的页面已经加载了jQuery,我能否在c#中执行以下操作?
webView.ExecuteScript("$(\"input#some_id\").val(\"user@example.com\")"));

目前这会抛出异常。我在试图找出:我是否应该尝试从cefsharp DLL中使用jQuery,还是必须坚持使用需要写五倍时间的标准旧式JavaScript…?

我希望一个程序员可以回答。我已经查阅了cefsharp的维基和论坛,但它们并没有提供太多线索;而我找到的唯一示例都是使用旧式JavaScript的。


JQuery 在 CefSharp 中应该可以正常工作,因为 ExecuteScript 只是在全局范围内运行您提供的所有内容。您所说的“被抛弃”能否更具体一些?您可能希望编写一些使用普通 JS(如 getElementById)的测试代码,并确认它是否正常工作,然后再尝试使用 jQuery,以减少可能出错的事情数量。 - Jack O'Connor
当然,这是一个好主意,事实上我已经成功地使用了普通的JS,但是当我尝试使用jQuery选择器等时,控制台会出现错误,例如$未被识别...所以我正在寻找应该如何包含jQuery并调用它的语法...我可能正在接近目标,但还没有到达。 - julian guppy
@julianguppy 这个问题解决了吗? - Roy Lee
我当时时间非常紧迫,所以我使用了executescript和evaluatescript方法来实现我想要的功能。虽然使用jquery会更容易,但我还是成功地完成了任务。 - julian guppy
2个回答

6

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

请参见下面我在一个项目中的代码片段。正如您所看到的,一旦IsLoading属性更改,我就调用一些方法来设置WebView中的内容,并通过调用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();
            }
        }
    }
}

我确实已经确认浏览器已加载,并且我有PropertyChanged事件等等...也许我在这里有些傻,但是我无法从中看出如何将jquery添加到已加载页面的dom中,然后使用jquery选择器调用引用dom中的项目...或者是在你调用的webViewInitialised()函数内的代码?还是registerJSObject?您能再详细解释一下吗?谢谢。 - julian guppy
嗨@julianguppy-抱歉,我没有意识到您需要帮助加载它。有一行代码是“LoadHtml(reader.ReadToEnd())”,在该代码中,reader是一个完整的HTML页面,其中包含了jQuery的压缩版本(请参见此文件:https://github.com/intninety/yaircc/blob/master/yaircc/UI/default.htm)。您可以忽略对registerJSObject的调用,这不是使用jQuery所必需的,这只是我从网页本身回调到程序集的一些东西。 - user1243584
我的情况是,我有一个已经加载的页面 - 比如来自tesco.com,我想分析该页面上的元素。Tesco.com没有jquery,我想知道是否可以将JQuery添加到dom中,然后开始使用它来选择页面中的元素?这样使用漂亮的jquery选择器分析页面会容易得多,虽然你的答案有点说是可能的,但我需要知道是否可以在事后添加它,然后使用它?感谢您迄今为止的回复,它们非常有用。 - julian guppy
1
在这种情况下,您需要通过ExecuteScript方法将jQuery自己加载到页面中,运行类似于此的JavaScript代码:https://dev59.com/gmox5IYBdhLWcg3wIQ5o#9413814。但是,如果您所在的页面已经包含了jQuery,则可能会遇到一些问题。 - user1243584

1
您在评论中更清楚地表达了您想要做的事情,即将jQuery加载到尚未具备它的页面中。 int0x90建议在本地副本的jQuery源上运行ExecuteScript可能适合您。但我想提醒您,许多页面不兼容所有额外的JS,因为它们的作者从未放置过。两个很好的例子是谷歌和Facebook。它们都定义了一个不是jQuery $$运算符,因此践踏它们几乎肯定会使它们崩溃。
基础CEF库公开了许多直接从C ++操纵DOM元素的方法,但CefSharp尚未公开,因为还没有太多需求。不过,这似乎是您在这里真正想要使用的东西。如果您看一下CefSharp源代码,公开它们可能并不需要太多工作,但我自己没有尝试过。如果您想尝试,请还可以发布问题https://groups.google.com/forum/#!forum/cefsharp

2
jQuery.noconflict应该使其兼容已经定义了“$”的页面。 - sparebytes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接