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

时间:2015-06-14 15:06:01

标签: 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是视图。第一种方法在View中,第二种方法在Controller中。第一种方法是在HTML表格中设置单元格,包括用户单击单元格时发生的情况。在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。不幸的是,对于其他控件,我有一个“实例化顺序”问题。在下面我试图将注释掉的行移动到它可以看到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
}

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

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

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

1 个答案:

答案 0 :(得分:1)

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

DOM并非完全类型安全,因此有时您只需要“知道”您正在处理的内容。文档通常假定使用JavaScript,因此他们并不真正关心类型安全等问题。