如何用ghcjs-dom

时间:2017-02-17 23:16:38

标签: css haskell ghcjs ghcjs-dom

我发现ghcjsghcjs-dom文档非常有限。这是这个基本的HTML文档。



h1 { font-family: Helvetica; }

p {font-family: Helvetica; color: blue; }

<h1>
Hello World
</h1>
<p>
This is my test document.
</p>
&#13;
&#13;
&#13;

我已经读过ghcjs只是将Haskell编译成JavaScript。如果我想用这个简单的文档填充DOM树,我需要外部函数接口(FFI),可能需要ghcjs-dom

具有讽刺意味的是将其称为&#34; 外部功能界面&#34;是JavaScript通常被认为是&#34; native &#34;到浏览器。所以那里有一点点术语​​混乱。

在这个非常简单的例子中,也许

让我们尝试一个操作DOM的简单示例。我有一个简单的HTML文档,我想 *将蓝色段改为红色或 *每秒来回切换一次(红色和蓝色之间)

如果ghcjs工具集甚至不能完成这些非常基本的测试用例并对其进行解释,我也不会看到它们如何实现更难的任务。这是我在Github上提出的一个问题,结论是ghcjs缺乏良好的on-boarding过程。

1 个答案:

答案 0 :(得分:3)

这是一个简短的自包含示例,它使用reflex-dom来执行您描述的红色/蓝色切换。这是epsilonhalbethis answer中包含的your earlier question代码的修改版本。

{-# LANGUAGE OverloadedStrings #-} 
{-# LANGUAGE ScopedTypeVariables #-} -- allows for local type declarations.
import Reflex
import Reflex.Dom
import Data.Text (Text, pack)
import Data.Map (Map)
import Data.Time.Clock (getCurrentTime)
import Control.Monad.Trans (liftIO)

webPage :: MonadWidget t m => m ()
webPage = do

  -- ticker Event fires once per second.
  ticker :: Event t TickInfo <- tickLossy 1.0 =<< liftIO getCurrentTime  

  -- counter Dynamic increases by one every second.
  counter :: Dynamic t Int <- foldDyn  (\_ n -> n+1) 0 ticker

  -- function to map from integer to red or blue style.
  let chooseColor :: Int -> (Map Text Text) 
      chooseColor n = "style" =: pack ("color: " ++ if (n `mod` 2) == 0 then "red" else "blue")

  -- redBlueStyle Dynamic changes each second.
  let redBlueStyle :: Dynamic t (Map Text Text) 
      redBlueStyle = fmap chooseColor counter

  -- insert an h1 elemnt.
  el "h1" $ text "Hello World!"

  -- insert a paragraph with Dynamic red blue style.
  elDynAttr "p" redBlueStyle $ text "This is my test document"

  return ()


css = "h1 {font-family: Helvetica;} p {font-family: Helvetica;}" 

main :: IO ()
main = mainWidgetWithCss css webPage

当然,reflex-dom(以及反射)是一个比ghcjs-dom更高级别的库,它带有你需要熟悉的一组概念(事件,动态,行为等)。< / p>

该示例的工作原理是创建一个动态地图,指定每秒从红色到蓝色交替的样式,并使用该动态地图为元素设置样式。

为清楚起见,此示例包含一些非严格要求的类型声明。

此项目:https://github.com/dc25/stackOverflow__how-to-change-h1-tags-with-ghcjs-dom包含上述代码。以下是基于浏览器的演示的链接:https://dc25.github.io/stackOverflow__how-to-change-h1-tags-with-ghcjs-dom/