how to code <h1> tags with ghcjs [closed]

一个人想着一个人 提交于 2019-12-11 06:54:41

问题


I have found the ghcjs documentation very limited. Here is this basic HTML document.

h1 { font-family: Helvetica; }

p {font-family: Helvetica; color: blue; }
<h1>
Hello World
</h1>
<p>
This is my test document.
</p>

Is ghcjs just a combinator, basically typing the HTML as an output string? Or does Haskell store a model of DOM somewhere?

My question is about all html tags and CSS, but maybe other tags have different features.


回答1:


You can use ghcjs with the library ghcjs-dom to work with the DOM .

From the title of your question, "how to code <h1> tags with ghcjs", and some of your comments, it looks like you are looking for a simple ghcjs/ghcjs-dom example that includes a few HTML tags. This program will generate your HTML and respond to a click on the h1 element:

import GHCJS.DOM (runWebGUI, webViewGetDomDocument)
import GHCJS.DOM.Document (getBody, createElement)
import GHCJS.DOM.Element (click, setInnerHTML)
import GHCJS.DOM.HTMLHeadingElement (castToHTMLHeadingElement)
import GHCJS.DOM.HTMLParagraphElement (castToHTMLParagraphElement)
import GHCJS.DOM.Node (appendChild)
import GHCJS.DOM.EventM (on)

main = runWebGUI $ \win -> do
        Just doc <- webViewGetDomDocument win
        Just body <- getBody doc

        Just h1 <- fmap castToHTMLHeadingElement <$> createElement doc (Just "h1")
        appendChild body $ Just h1
        setInnerHTML h1 (Just "Hello World")
        on h1 click $ setInnerHTML h1 (Just "Clicked")

        Just p <- fmap castToHTMLParagraphElement <$> createElement doc (Just "p")
        appendChild body $ Just p
        setInnerHTML p (Just "This is my test document.")

        return ()

This project: https://github.com/dc25/stackOverflow__how-to-code-h1-tags-with-ghcjs contains the above code. Here is a link to a browser based demo: https://dc25.github.io/stackOverflow__how-to-code-h1-tags-with-ghcjs/ The page changes if you click the "Hello World" header.

The ghcjs compiler output includes an index.html page. Ghcjs will not overwrite that page if it already exists so you can safely edit it after it is created. This allows you to directly include your css file.

Regarding documentation, this page: https://hackage.haskell.org/package/jsaddle-dom-0.4.0.1/docs/ contains useful links related to ghcjs-dom functionality.




回答2:


First of all - as @Cubic already said - I think you are confused what GHCJS is.

GHCJS is a Compiler that lets you compile Haskell code to Javascript - rendering a simple page of html/css is not the task it was designed for. It is "Mit Kanonen auf Spatzen schießen" as we say in German - or shorter overkill.

So what would I use it for writing a front-end to a given haskell backend is really nice, you can share all your existing types and get all the maintainability and safety you have in the haskell eco-system.

But even if you don't have a haskell backend and you strife for novelty and good ideas - GHCJS might interest you, I myself am quite new to functional reactive programming, and having tried purescript(with pux) before now learning reflex/reflex-dom (my choice of front-end dsl) is a challenge for my brain and a delight - I know this paragraph is quite opinionated, but the abstractions presented in reflex seem right and seem to make clear some of the shortcomings of other functional reactive frameworks…

So how would one render the above in with the aforementioned libraries:

{-# LANGUAGE OverloadedStrings   #-}
import           Reflex
import           Reflex.Dom

main :: IO ()
main = mainWidgetWithCss "h1 {font-family: Helvetica;} p {font-family: Helvetica; color: blue;}" $ do
  el "h1" $ text "Hello World!"
  el "p" $ text "This is my test document"

This is - as I said - overkill - you get a full run-time, a big chunk of js when some plain html/css would have sufficed. But for generating a complex UI in reusable components GHCJS might be the right choice.

The following is one of the more complex components I have yet written - it models a list of buttons that I can expand when clicking on the rightmost button, or shrink to the size of one of the other buttons (i use this for something like a "rate this X stars" but the stars can be arbitrary many).

listWidget :: MonadWidget t m => Int -> m (Event t Int)
listWidget n = leftmost <$> traverse button' [(-1)..(n+1)]

listWidget2 :: MonadWidget t m => m ()
listWidget2 = mdo
  clicked <- switchPromptlyDyn <$> widgetHold (listWidget (-1))
                                              (listWidget <$> clicked)
  return ()

button' :: (MonadWidget t m, Show a) => a -> m (Event t a)
button' val = (fmap $ const val) <$> button (text . pack $ show val)

UPDATE:

The problem that plain Javascript has is scalability if you have a large amount of Javascript maintaining and changing code gets error prone and tedious because of the lacking type system and the dynamic nature. To remedy these problems there have come up a vast number of "compile-to-JS" languages - Haskell with GHCJS being one of them.



来源:https://stackoverflow.com/questions/42254610/how-to-code-h1-tags-with-ghcjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!