我正在尝试scalajs,对于如何使用org.scalajs.dom.html包访问DOM元素感到非常困惑。
通过反复试验,我发现某些元素需要使用asInstanceOf强制转换为某些类型,而有些则不需要。是否需要在何时何地使用asInstanceOf的一般规则?

例如,假设我有一个ID为inputmyinput元素。为了访问输入的值,我需要使用asInstanceOf

val content = document.getElementById("myinput").asInstanceOf[html.Input].value


但是,当需要在id为contentdiv中显示contentdiv时,当我没有在asInstanceOf元素上使用div时,编译器不会抱怨:

val mydiv = document.getElementById("contentdiv")
mydiv.innerHTML = content


另外,作为奖励,是否可以找到所有可能的asInstanceOf参数并将其映射到实际HTML元素的中心位置?

最佳答案

getElementById的签名是

def getElementById(id: String): DOMElement


并且DOMElement被定义为

trait DOMElement extends js.Object {
  var innerHTML: String = js.native

  def appendChild(child: DOMElement): Unit = js.native
}


因此,每当调用getElementById时,您都会得到一个DOMElement,并且只能对其执行的操作是innerHTMLappendChild

这就是为什么最后一个示例无需显式强制转换的原因。

但是DOMElement是非常通用的类型。有时您知道getElementById将返回-例如-一个<input>元素。

到那时,您可以使用asInstanceOf告知编译器您所拥有的这些额外知识。

document.getElementById("myinput").asInstanceOf[html.Input].value
                                      ^
                                      |
          hey compiler, I KNOW this is going to be an html.Input,
            please let me do my things and explode otherwise.


不用说,使用asInstanceOf时要小心。如果您输入的是错误的,则编译器将无法从运行时崩溃中解救您。

10-07 12:55