Purescript 中的 getElementById

getElementById in Purescript

我是 Purescript 的新手,所以这可能是一个幼稚的问题。

我想编写一个 Purescript 函数,它从浏览器上的 HTML 输入元素读取输入,并将一些输出写入另一个 HTML 输入元素。

使用普通 Javascript 就和 document.getElementById('output').value = myFun(document.getElementById('input')); 一样简单。我如何仅使用 Purescript 来做到这一点?

我使用 Purescript 的外部函数接口 (FFI) 功能如下。

定义您的 Purescript 模块,导入您要使用的外部函数。这里我们导入了两个函数。

-- Main.purs
foreign import getElementById :: String -> Effect String
foreign import setElementById :: String -> String -> Effect Unit 

现在创建一个 Javascript 同名但扩展名为 .js 的文件。我们将从这里导出 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;
    };
};

现在我们可以在 Purescript 文件中调用 getElementByIdsetElementById 函数。

编辑:

我注意到我的回答不符合要求 - 我只是设置了一个元素值。如果我找到更多时间,我可能还会添加阅读元素值部分,但你应该能够从已经提供的提示中猜出如何做到这一点:-)


一般来说,在使用 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

直接 DOM 操作可能不是开始构建更大项目或开始使用这种非常棒的语言进行冒险的最佳方式。另一方面,它有时会有用 ;-)