我已成功地将 CefSharp 嵌入到 .NET 4.0 应用程序中。是不是可以让 jQuery 调用在 DOM 上工作?

Posted

技术标签:

【中文标题】我已成功地将 CefSharp 嵌入到 .NET 4.0 应用程序中。是不是可以让 jQuery 调用在 DOM 上工作?【英文标题】:I have successfully embedded CefSharp into a .NET 4.0 application. Is it possible to get jQuery calls working on the DOM?我已成功地将 CefSharp 嵌入到 .NET 4.0 应用程序中。是否可以让 jQuery 调用在 DOM 上工作? 【发布时间】:2013-02-04 10:01:12 【问题描述】:

我想知道这是否可能。我已经浏览了 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。

【问题讨论】:

JQuery 在 CefSharp 中应该可以正常工作,因为 ExecuteScript 只是在全局范围内运行您提供的所有内容。您能否更具体地说明“被淘汰”的含义?在尝试使用 jQuery 之前,您可能想使用普通的旧 JS(如 getElementById)编写一些测试代码并确认其工作正常,以减少可能出错的事情的数量。 是的,这样做当然是个好主意,而且确实我得到了普通的旧 JS 工作正常,但是当尝试 gto 执行 jquery 选择器等时。我在控制台上收到一个错误,说 $ 是无法识别...所以我正在寻找的是包含 jquery 并调用它的语法...我可能越来越近了,但我还没有 @julianguppy 这个问题解决了吗? 好吧,我承受着巨大的时间压力,以至于我结束了使用 executescript 和 evaluatescript 方法来实现我想要的结果,使用 jquery 会更容易,但我没有它就可以工作 【参考方案1】:

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

请参阅下面的 sn-p,了解我如何在我的一个项目中做到这一点。正如你所看到的,一旦 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("0WebBrowser", 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?你能再详细一点吗?谢谢 嗨@julianguppy - 对不起,我没有意识到你需要帮助加载它。有一行写着“LoadHtml(reader.ReadToEnd())”,在那个阅读器中是一个完整的 HTML页面,其中包含 jQuery 的缩小版本(请参阅此文件:github.com/intninety/yaircc/blob/master/yaircc/UI/default.htm)。您可以忽略对 registerJSObject 的调用,这不是使用 jQuery 所必需的,它只是我用来从网页本身回调到程序集的东西。 我的情况是我有一个已经加载的页面 - 比如来自 tesco.com,我想分析该页面上的元素。 Tesco.com 没有 jquery 我想知道我可以将 JQeury 添加到 dom 中,然后开始使用它来选择页面中的元素吗?从而使使用漂亮的 jquery 选择器分析页面变得容易一百万倍?尽管您的回答有点说是的,但我可能需要知道您可以在事后添加它然后使用它吗?感谢您到目前为止的回复,它们很有用 在这种情况下,您需要自己通过 ExecuteScript 方法将 jQuery 加载到页面中,运行一段类似于此的 JavaScript:***.com/a/9413814/1243584 如果您所在的页面已经有 jQuery包括在内,您可能会遇到一些问题。【参考方案2】:

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

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

【讨论】:

jQuery.noconflict 应该使它在已经定义了$的页面上兼容

以上是关于我已成功地将 CefSharp 嵌入到 .NET 4.0 应用程序中。是不是可以让 jQuery 调用在 DOM 上工作?的主要内容,如果未能解决你的问题,请参考以下文章

使用CefSharp在.NET中嵌入Google kernel

在WPF中使用CefSharp嵌入浏览器

使用CefSharp在.Net程序中嵌入Chrome浏览器——Cookie

使用CefSharp在.Net程序中嵌入Chrome浏览器——Javascript交互

使用CefSharp在.Net程序中嵌入Chrome浏览器——Javascript交互

从 CefSharp 1 中的 javascript 调用 .Net - wpf