在 Haxe 中为 HTML 元素进行元素访问转换

Casting for element access in Haxe for HTML-elements

如果我们想在 canvas 上绘制一些东西,我们需要获取它的二维上下文。 我在项目的 index.html 中有一个 canvas 元素:

 <body>
    <canvas id="canv" width="200" height="200"></canvas>
 </body>

所以现在我需要访问该元素,好的,让我们编写代码:

var cans:CanvasElement = Browser.document.getElementById("canv");

在编译阶段我得到错误:

src/Main.hx:32: characters 2-78 : js.html.Element should be js.html.CanvasElement

但是如果我们使用不安全的转换,已经没问题了:

var cans:CanvasElement = cast Browser.document.getElementById("canv");

一切正常,我可以访问并可以获取 2D 上下文或进行一些设置,例如:

cans.width = cans.height = 800;
cans.style.backgroundColor = 'rgba(158, 167, 184, 0.4)';

是的,我知道,"if it works - don't fix",我大致理解一切正常,原则上我得到我需要的东西,什么时候投,但是谁能给我解释一下这个过程吗? 这是什么意思 - js.html.Element 应该是 js.html.CanvasElement?我才开始学习 Haxe(尤其是编程),我很高兴,我可以做一些可行的事情,但我想知道,为什么它能工作,为什么不能工作。

js.html.Element should be js.html.CanvasElement

这只是意味着编译器期望类型CanvasElement(因为这是cans变量的类型提示告诉它的),但是遇到其他东西(在这种情况下为 Element)。您正在尝试将 getElementById() 返回的值分配给 cans,但是 getElementById() returns 和 Element.

因为 Element CanvasElement 更不具体 CanvasElement 扩展 Element),你不能只分配ElementCanvasElement - 谁能说它不是 DivElement 或任何其他选项?这只能在执行代码时决定/编译器无法知道这一点,因此会出现错误 (runtime vs compile time).

在这种情况下效果很好,因为您知道 ID 为 "canv" 的元素实际上是 CanvasElement,因此您可以将通过告诉编译器你知道你在用 cast 做什么。当返回值实际上是其他类型时会出错。

Gama11 回答的真好。有时在代码中创建 canvas 更容易,就像这条简单的蛇。 https://try.haxe.org/#D0324 其次,有时您可以使用另一个变量并让抽象内容自动为您转换它,但我认为您最终可能仍会在代码中使用转换。

var canvas = document.createCanvasElement(); 
var dom = canvas; 
var style = dom.style; 
// HTMLDocument is needed here so dom is infered to
// HTMLDocument type and the canvas is auto cast, 
// via the use of the secondary variable.

这里的问题并不是真正的 Haxe,问题是 HTML5 进化或追溯重新设计的方式,Haxe 只是试图包装一些动态的东西,并且与提供的一些尝试不一致适当的编译器检查和一致性,通常当类型像加载数据一样进入 Haxe 时,你必须为 Haxe 转换它们,但你只有一个风险点,从那时起编译器可以帮助你。在某些情况下,您可以更明确地使用演员表:

var style = cast( canvas, HTMLDocument ).style;

告诉 Haxe 您期望如何施放它。对于一些不太动态的目标,Haxe 可以在类型系统上做得更好,但 js 如此松散的事实意味着尽管有奇怪的复杂性,但使用 Haxe 对于 js 编码来说甚至更强大。坚持使用 Haxe,它有助于您对多种语言的一般代码理解。