我对Purescript非常陌生,所以这可能是个幼稚的问题。
我想编写一个Purescript函数,该函数从浏览器上的HTML输入元素读取输入,并将一些输出写入另一个HTML输入元素。
在普通的Javascript中,它很简单:document.getElementById('output').value = myFun(document.getElementById('input'));
。如何只用Purescript实现这个功能呢?
我对Purescript非常陌生,所以这可能是个幼稚的问题。
我想编写一个Purescript函数,该函数从浏览器上的HTML输入元素读取输入,并将一些输出写入另一个HTML输入元素。
在普通的Javascript中,它很简单:document.getElementById('output').value = myFun(document.getElementById('input'));
。如何只用Purescript实现这个功能呢?
编辑:
我注意到我的回答不符合要求 - 我只是设置了一个元素值。如果我有更多时间,我可能会添加从元素值读取的代码段,但是你应该能够从已提供的提示中猜出如何实现它:-)
一般来说,在使用PureScript时,您需要使用一些高级框架来操作DOM,例如:halogen、react-basic、concur、spork、elmish、flare、hedwig、flame(当然我可能漏掉了一些其他的 - 对此感到抱歉)。
但是,如果您真的想手动改变DOM,请不要感到惊讶,因为这并不像命令式JavaScript那样愉快。这是有意的 - PureScript有将效果与纯函数分离的能力,我们必须在每个步骤中使用Effect
。另一方面,这赋予了我们一种独特的能力,可以理解代码并确保副作用可能发生的位置以及我们程序的哪些部分是纯粹的。
所以让我们使用低级别的purescript-web-html。这个库非常底层,但是在DOM API周围提供严格的类型,因此就像我说的那样,它需要相当多的手动值传递:
module Main where
import Prelude
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Web.DOM.Document (toNonElementParentNode)
import Web.DOM.Element (setAttribute)
import Web.DOM.NonElementParentNode (getElementById)
import Web.HTML (window)
import Web.HTML.HTMLDocument (toDocument)
import Web.HTML.Window (document)
main :: Effect Unit
main = do
w ← window
d ← document w
maybeElement ← getElementById "test-input" $ toNonElementParentNode $ toDocument d
case maybeElement of
Nothing → pure unit
Just elem → do
setAttribute "value" "new-value" elem
使用无中间变量的点儿式风格可以将其缩短一些:
main :: Effect Unit
main = window >>= document >>= toDocument >>> toNonElementParentNode >>> getElementById "test-input" >>= case _ of
Nothing → pure unit
Just elem → setAttribute "value" "new-value" elem
-- Main.purs
foreign import getElementById :: String -> Effect String
foreign import setElementById :: String -> String -> Effect Unit
现在创建一个相同名称但扩展名为.js
的Javascript文件。我们将从这里导出JS函数以供Purescript使用。
// Main.js
"use strict";
exports.getElementById = function(id) {
return document.getElementById(id).value;
};
exports.setElementById = function(id) {
return function(value) {
document.getElementById(id).value = value;
};
};
getElementById
和setElementById
函数。getElementById
不是纯函数,因为它依赖于文档的当前状态,而不仅仅是输入的字符串。文档中可能缺少该元素,给定元素可以是 HTML input
之外的其他元素(value
属性可能丢失)。value
可以在调用之间更改,因此对此函数的后续调用返回不同的结果,违反了引用透明属性。setElementById
应该被包装在一个JS端的 Effect
表示的 function()
中。 - paluhEffect (Maybe String)
或类似的内容。 - chtenb
canvas
渲染层。 - paluh