【问题标题】:CefSharp does not marshal DOM nodesCefSharp 不编组 DOM 节点
【发布时间】:2020-10-16 03:44:46
【问题描述】:

当我在 CEFSharp 中使用 EvaluateScriptAsync() 执行 js 时,我可以返回原始类型,如字符串或数组。例如,以下工作:

var result = await Browser.EvaluateScriptAsync("Array.from(document.getElementsByTagName('input')).map(element => element.value)");
if (result.Success && result.Result != null)
{
    dynamic values = result.Result;
    foreach (dynamic value in values)
    {
        MessageBox.Show($"Value is: {value}");
    }
}

但是一旦我尝试获取一个 DOM 元素,无论是一个还是一个列表,我都会得到null

var result = await Browser.EvaluateScriptAsync("Array.from(document.getElementsByTagName('input'))");
// `result.Success` is `true`, `result.Result` is `null`

我以为 CEFSharp 只知道如何编组原始类型,但对象字面量也可以:

var result = await Browser.EvaluateScriptAsync("({ a: 1, b: 'hello' })");
if (result.Success && result.Result != null)
{
    dynamic obj = result.Result;
    MessageBox.Show($"{{ a: {obj.a}, b: {obj.b} }}");
}

结果证明只有 CEFSharp 不知道如何编组 DOM 对象。

为什么?是否有解决方案或解决方法?

【问题讨论】:

  • 仅从 DOM 节点返回您需要的数据,参见github.com/cefsharp/CefSharp/wiki/… 示例(本节底部使用array.map() 的示例)。
  • 这很不幸,但他们没有这么说(至少没有明确表示)。他们说可以返回对象,并且不会对 DOM 节点发出任何警告。事实上,即使像 CSSStyleDeclaration 这样的对象也可以工作。
  • 如果你需要返回一个复杂的对象图然后转换成 JSON 然后使用你最喜欢的 .Net JSON 库。 Javascript 在不同的进程中执行,因此最好只返回您需要的内容。任何拥有 GitHub 帐户的人都可以编辑 wiki,欢迎您做出一些改进。
  • 问题是我还需要在对象上调用方法。
  • 我想知道,它不能编组 DOM 对象的原因是什么?

标签: javascript c# dom cefsharp


【解决方案1】:

首先,重要的是要了解Javascript 是在渲染过程中执行的。 EvaluateScriptAsync 的结果实际上是一个DTO,我们创建一个对象来表示执行脚本的结果。

目前无法返回 HTMLElement 或任何具有循环引用的对象。

如果我们看 `HTMLElement 作为一个具体的例子,它将有一个 parentElement/parentNode 并且父节点有包含节点本身的子节点。您最终也会遍历整个 DOM 树。

CEF 对其CefV8Value 类型的类型支持非常有限,因此很难做任何太花哨的事情。见this

我们可能会添加一个扩展方法,将用户脚本包装在 IIFE 中,并进行一些 instanceof HTMLElement 样式类型检查以返回 HTML 元素的精简表示。请参阅this,了解我如何伪造支持以返回Promise

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-01-19
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 2013-12-19
  • 2021-01-22
  • 2015-08-17
  • 2015-05-20
相关资源
最近更新 更多