在 Scala.js 中应该使用 `target` 而不是 `srcElement`

Should be using `target` rather than `srcElement` in Scala.js

我有一些 Scala.js 代码,当目标浏览器是 Chrome 时可以正常工作,但当它是 Firefox 时就不行了。我被告知我不应该使用 srcElement 而应该使用 target。但是我不知道如何访问 target.

private def TD(locId: Location, personId: Person): HTMLTableCellElement = {
  val res = td(style := myPeopleTable_td).render
  res.onclick = { (e: dom.Event) => c.clickTD(e.srcElement)}
  res.id = Id(locId, personId).toString
  cells += (Id(locId, personId) -> res)
  res
}
def clickTD(element: Element): Unit = {
  val idOption = Id.parse(element.id)
  idOption.foreach(id => {
    locIdx = Location.indexOf(id.locId)
    personIdx = Person.indexOf(id.personId)
    localSync()
    v.personValueBox.focus()
  })
}

作为解释,c 是控制器,v 是视图。第一个方法在视图中,第二个方法在控制器中。第一种方法是在 HTML table 中设置一个单元格,包括用户单击该单元格时发生的情况。在 clickTD() 中,代码需要知道点击了什么——它需要以某种方式获取 HTML 元素的 'id',该元素已预先设置,以便可以查找模型对象。

如果我尝试将 e.srcElement 替换为 e.target,结果如下:

[info] Compiling 1 Scala source to C:\dev\v2\atmosphere\js\target\scala2.11\classes...
[error] C:\dev\v2\atmosphere\js\src\main\scala\simple\View.scala:145: type mismatch;
[error]  found   : org.scalajs.dom.raw.EventTarget
[error]  required: org.scalajs.dom.Element
[error]     (which expands to)  org.scalajs.dom.raw.Element
[error]     res.onclick = { (e: dom.Event) => c.clickTD(e.target)}
[error]                                                   ^
[error] one error found
[error] (atmosphereJS/compile:compile) Compilation failed
[error] Total time: 1 s, completed 15-Jun-2015 02:14:41

谢谢@ochrons,你用 res 代替 e.target 的建议行得通。不幸的是,对于其他控件,我遇到了 'order of instantiation' 问题。在下文中,我试图将注释掉的行移动到可以看到 res:

的位置
private def button_TD_Tog(idT: Row): HTMLTableCellElement = {
  val idsStr: String = idT.toString
  val buttonWidget = button(
    style := myToggleButton, 
    name := "button", 
    id := idsStr
    //onclick := { (e: dom.Event) => c.clickToggleButton(e.srcElement)}
  )
  val res = td(style := myToggleButtonCol, buttonWidget).render
  buttonWidget.onclick = { (e: dom.Event) => c.clickToggleButton(res)}
  res.id = idsStr
  buttonTDs += (idT -> res)
  res
}

我(认为我)需要 resbuttonWidget 在分配给 onclick 之前都存在,但编译器不识别 onclick。我发现自己正在搜索一些 API 文档来帮助我。我怀疑它是否存在(我发现 Scala.js 文档非常好,但并不全面)。也许我应该看看 DOM 本身...

现在来看一个似乎适用于所有情况的简单通用解决方案示例,根据您对强制类型的建议:

c.clickPushButton(e.target.asInstanceOf[dom.Element])}

如果你只需要知道你的td元素被点击了,那么你可以直接在闭包中使用c.clickTD(res)。但是,如果 td 中有可以单击的元素,则只需将事件的 target 强制转换为 Element 即可使用该事件的 target。在这种情况下,您的内部元素必须将点击事件冒泡到 td 元素。

DOM 不是完全类型安全的,因此有时您只需要 "know" 您正在处理的内容。该文档通常假定 JavaScript,因此他们并不真正关心类型安全之类的事情。