我有一些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之前需要res
和buttonWidget
存在,但编译器无法识别onclick。我发现自己正在寻找一些API文档来帮助我。我怀疑它是否存在(我发现Scala.js文档非常好,但并不全面)。也许我应该关注DOM本身......
现在以一个简单的通用解决方案为例,根据你强制类型的建议,似乎适用于所有情况:
c.clickPushButton(e.target.asInstanceOf[dom.Element])}
答案 0 :(得分:1)
如果您只需要知道已点击了td
元素,那么您可以直接在闭包中使用c.clickTD(res)
。但是,如果td
中有可以点击的元素,那么只需将其作为target
投射即可使用该事件的Element
。在这种情况下,您的内部元素必须将click事件冒泡到td
元素。
DOM并非完全类型安全,因此有时您只需要“知道”您正在处理的内容。文档通常假定使用JavaScript,因此他们并不真正关心类型安全等问题。