CefSharp 不封送 DOM 个节点

CefSharp does not marshal DOM nodes

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

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 个对象。

为什么?有解决方案或解决方法吗?

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

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

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

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

我们可能会添加一个扩展方法,将用户脚本包装在 IIFE 中,并进行一些 instanceof HTMLElement 样式类型检查 return [=31] 的精简表示=] 元素。有关我如何捏造对 returning a Promise.

支持的示例,请参阅 this