请参阅以下示例on Ellie:
module Main exposing (main)
import Html exposing (..)
import Html.Attributes exposing (style)
import Html.Events exposing (Options, onClick, onWithOptions)
import Json.Decode as JD
import Json.Decode.Extra exposing ((|:))
import Result exposing (withDefault)
import String as S
main : Program Never Model Msg
main =
Html.program
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
init : ( Model, Cmd Msg )
init =
( Model "", Cmd.none )
type alias Model =
{ message : String
}
type Msg
= Zoom MouseWheelEvent
| Clicked
type alias MouseWheelEvent =
{ deltaX : Float
, deltaY : Float
, clientX : Float
, clientY : Float
}
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Zoom e ->
( { model | message = toString e }, Cmd.none )
Clicked ->
( { model | message = "Clicked!" }, Cmd.none )
decodeMouseEvent : JD.Decoder Msg
decodeMouseEvent =
JD.map Zoom
(JD.succeed MouseWheelEvent
|: mouseAttribute "deltaX"
|: mouseAttribute "deltaX"
|: mouseAttribute "deltaX"
|: mouseAttribute "deltaX"
)
mouseAttribute : String -> JD.Decoder Float
mouseAttribute k =
JD.at [ k ] JD.string |> JD.andThen readFloat
readFloat : String -> JD.Decoder Float
readFloat n =
JD.succeed (withDefault 0 (S.toFloat n))
view : Model -> Html Msg
view m =
div []
[ p [] [ text <| "message: " ++ m.message ]
, div
[ onWithOptions "mousewheel" (Options True True) decodeMouseEvent
, onClick Clicked
, style
[ ( "height", "250px" )
, ( "width", "250px" )
, ( "background-color", "green" )
]
]
[ p [] [ text "Zoom here" ]
]
]
subscriptions m =
Sub.none
我想捕获特定元素上的mousewheel事件。这与在SVG图像上创建缩放效果有关。
根据示例,如果我将侦听器附加到特定元素,则不会调用update
函数。该事件似乎被文档正文捕获,但未达到我的目标元素。那么如何让我的事件处理程序触发?
我很欣赏它可以通过端口执行此操作,但是当我只对在特定元素上发生时捕获它时,抓住在document.body
级别发生的事情似乎是错误的。
是否只将mousewheel
视为文档级事件?
答案 0 :(得分:6)
事件被触发,但您的解码器失败,因为字段event.deltaX
,event.deltaY
等不是字符串而是浮点数。如果解码器失败,AFAIK Elm会默默地忽略该事件。如果我改变解码器,它可以工作:
decodeMouseEvent : JD.Decoder Msg
decodeMouseEvent =
JD.map Zoom
(JD.succeed MouseWheelEvent
|: mouseAttribute "deltaX"
|: mouseAttribute "deltaX"
|: mouseAttribute "deltaX"
|: mouseAttribute "deltaX"
)
mouseAttribute : String -> JD.Decoder Float
mouseAttribute k =
JD.at [ k ] JD.string |> JD.andThen readFloat
readFloat : String -> JD.Decoder Float
readFloat n =
JD.succeed (withDefault 0 (S.toFloat n))
为:
decodeMouseEvent : JD.Decoder Msg
decodeMouseEvent =
JD.map Zoom
(JD.succeed MouseWheelEvent
|: JD.field "deltaX" JD.float
|: JD.field "deltaY" JD.float
|: JD.field "clientX" JD.float
|: JD.field "clientY" JD.float
)