2017-01-11 3 views
1

Ich möchte das Attribut html eines Elements in Elm kennen, zum Beispiel ihre Koordinaten. Ich habe es mit Json.Decode versucht.Ich möchte das Attribut html eines Elements in Elm kennen

Ich bin neu in Elm, und das ist für Lernzwecke.

Dies ist ein einfacher Code, ich bin mit Elm 0,18:

module Stamps exposing (..) 

import Html exposing (..) 
import Html.Attributes exposing (..) 
import Html.Events exposing (..) 


type alias Model = 
    {} 


type Msg 
    = NoOp 
    | Clicking 


model : Model 
model = 
    {} 


update : Msg -> Model -> (Model, Cmd Msg) 
update msg model = 
    case msg of 
     NoOp -> 
      (model, Cmd.none) 

     Clicking -> 
      let 
       _ = 
        Debug.log "msg1" model 
      in 
       (model, Cmd.none) 


view : Model -> Html Msg 
view model = 
    div 
     [ Html.Attributes.style 
      [ ("backgroundColor", "blue") 
      , ("height", "300px") 
      , ("width", "300px") 
      , ("position", "relative") 
      , ("left", "100px") 
      , ("top", "50px") 
      ] 
     , Html.Attributes.class 
      "parent" 
     ] 
     [ div 
      [ Html.Attributes.style 
       [ ("background-color", "#3C8D2F") 
       , ("cursor", "move") 
       , ("width", "100px") 
       , ("height", "100px") 
       , ("border-radius", "4px") 
       , ("position", "absolute") 
       , ("color", "white") 
       , ("display", "flex") 
       , ("align-items", "center") 
       , ("justify-content", "center") 
       ] 
      , Html.Attributes.class 
       "children" 
      , Html.Events.onClick Clicking 
      ] 
      [] 
     ] 


subscriptions : Model -> Sub Msg 
subscriptions model = 
    Sub.none 


main : Program Never Model Msg 
main = 
    Html.program 
     { init = (model, Cmd.none) 
     , update = update 
     , view = view 
     , subscriptions = subscriptions 
     } 

Antwort

6

Also ich bin nicht wirklich sicher, welche der Offsets speziell bekommen Sie versuchen, aber ich denke, das wird gesetzt Sie auf dem richtigen Weg. Zuerst müssen Sie Ihre Msg ADT's anpassen, um ein Tupel für die Koordinaten zu haben.

type Msg 
    = NoOp 
    | Clicking (Int, Int) 

Angenommen, Sie möchten nur bei der Protokollierung der Koordinaten bleiben, können Sie dies verwenden. Denken Sie daran, dass Sie in der Musterübereinstimmung zerstören können, wenn Sie brauchen.

update : Msg -> Model -> (Model, Cmd Msg) 
update msg model = 
    case msg of 
     NoOp -> 
      (model, Cmd.none) 

     Clicking cs -> 
      let 
       _ = 
        Debug.log "coords" cs 
      in 
       (model, Cmd.none) 

Sie benötigen einen Json.Decode.Decoder zu diesem Tupel.

import Json.Decode as Decode exposing (Decoder) 


coordsDecoder : Decoder (Int, Int) 
coordsDecoder = 
    Decode.field "target" <| 
     Decode.map2 (,) 
      (Decode.field "offsetWidth" Decode.int) 
      (Decode.field "offsetHeight" Decode.int) 

Und schließlich müssen Sie die on Decoder nehmen etwas mit dem Event Objekt von einem JavaScript-Click-Ereignisse zurückgegeben. Dieser Decoder erhält die Koordinaten, dann Decode.map s Clicking msg type.

Html.Events.on "click" (Decode.map Clicking coordsDecoder) 

Mit diesem Decode.field "target" ... können Sie Dekodierung beginnen, was Sie aus dem Zielelement möchten.


Stilistisch sind Sie mit exposing (..) alle der Html.* Funktionen in Umfang importieren, aber du bist immer noch alles prefixing was ziemlich überflüssig ist. Sie können einfach style anstelle von Html.Attributes.style verwenden. Haben Sie keine Angst zu verwenden as ->Html.Attributes as Attr.

0

Ausgezeichnete Antwort, falls ich versuche, die Koordinaten in Bezug auf den Browser zu erhalten, falls der Stil links und oben keine Definition sind. Ich suche eine Lösung und fand diese

offsetParent : a -> Decoder a -> Decoder a 
 
offsetParent x decoder = 
 
    Decode.oneOf 
 
    [ field "offsetParent" <| Decode.null x 
 
    , field "offsetParent" decoder 
 
    ]

Verwandte Themen