目标是window.addEventListener("popstate", ...
从 GHCJS 代码调度的事件中触发。
到目前为止尝试过
GHCJS.DOM 不起作用
w <- currentWindowUnchecked
e <- newPopStateEvent "popstate" Nothing
dispatchEvent_ w e
Language.Javascript.JSaddle 不起作用
e <- newPopStateEvent "popstate" Nothing
jsg "window" ^. jsf "dispatchEvent" (toJSVal e)
FFI 不工作
foreign import javascript unsafe "window.dispatchEvent($1)" dispatchIt :: JSVal -> JSM ()
e <- newPopStateEvent "popstate" Nothing
dispatchIt =<< toJSVal e
调试输出
这确实有效:
e <- newPopStateEvent "popstate" Nothing
w <- currentWindowUnchecked
jsg "console" ^. js2 "log" (toJSVal e) (toJSVal w)
并产生有趣的结果
如您所见,JSVal
s 是正确的,我们可以在 JavaScript 控制台中运行该命令。
最近的尝试
然后我发现如果我在 之后立即抛出错误dispatchEvent
,它就会触发。
foreign import javascript unsafe "window.foo()" foo :: JSM ()
w <- currentWindowUnchecked
e <- newPopStateEvent "popstate" Nothing
dispatchEvent_ w e
liftJSM foo
这会导致预期的结果dispatchEvent_
,但显然不会这样做,因为它会导致运行时错误。
所以我想这可能是一个syncPoint
还是没有骰子
!e <- newPopStateEvent ("popstate" :: Text) Nothing
!() <- dispatchEvent_ w e
liftJSM GHCJS.DOM.syncPoint
运行代码
你可以自己试试这个
git clone -b crud-example https://gitlab.com/fresheyeball/Shpadoinkle.git
cd Shpadoinkle
./examples/servant-crud/run-crud.sh
localhost:8080
在浏览器中打开,然后单击单词"ECHO"
。
相关代码:
https://gitlab.com/fresheyeball/Shpadoinkle/blob/crud-example/router/Shpadoinkle/Router.hs#L100 https://gitlab.com/fresheyeball/Shpadoinkle/blob/crud-example/examples/servant-crud /View.hs#L43