【问题标题】:Image does not resize when resizing the browser window (elm)调整浏览器窗口大小时图像不调整大小(榆树)
【发布时间】:2016-01-01 10:07:36
【问题描述】:

我正在尝试监听“resize”事件并相应地更改图像大小。但是图像大小不会改变。我认为原因是我的“onResize”函数在错误的地方。但我不知道在这个框架中还有什么地方可以嵌入它。抱歉,如果这听起来微不足道,但我已经浏览了很长时间的文档并且找不到解决方案。完整的elm代码如下:

module App where

import Html exposing (..)
import Html.Attributes exposing (attribute, class, style, src, width, height)
import Html.Events exposing (on)
import Json.Decode exposing (object2, (:=), int)
import StartApp.Simple exposing (start)


-- MODEL

type alias Model = 
  { width : Int
  , height : Int
  }

init : Model
init = { width = 800, height = 800 }

-- UPDATE

type Action = NewSize Int Int

update : Action -> Model -> Model
update (NewSize w h) model = 
  { model | width = w, height = h }

-- VIEW

view : Signal.Address Action -> Model -> Html
view address model =
  div
    [ class "container", onResize address ]
    [ div
      []
      [ img
        [ src "http://package.elm-lang.org/assets/elm_logo.svg"
        , width model.width
        , height model.height
        ]
        []
      ] 
    ]

onResize : Signal.Address Action -> Attribute
onResize address =
  on "resize" (getWidthHeight view) (\(w, h) -> Signal.message address (NewSize w h))

getWidthHeight : a -> Json.Decode.Decoder ( Int, Int )
getWidthHeight view =
  object2 (,) ("innerWidth" := int) ("innerHeight" := int)


-- MAIN

main : Signal Html
main =
  start
    { model = init
    , update = update
    , view = view
    }

【问题讨论】:

    标签: javascript css elm dom-events


    【解决方案1】:

    关于您的解决方案的一些要点。

    • 调整大小处理程序似乎确实附加到了正确的容器。很好。
    • 您似乎将视图函数作为参数 getWidthHeight 传递。
      • 这不起作用,但你的 getWidthHeight 实际上并没有将它用于任何事情,所以我认为它也不会伤害任何东西。

    我相信您要在 getWidthHeight 中使用的视图是 json 的一部分 解码器规则访问视图以获取窗口,然后提取 innerWidth 和 innerHeight 值。您正在尝试访问view.innerWidthview.innerHeight

    鉴于 resize 事件属性的描述,我很确定这是您想要的解码器。

    getWidthHeight : Json.Decode.Decoder (Int, Int)
    getWidthHeight =
      object2
        (,)
        (Json.Decode.at ["view", "innerWidth"] int)
        (Json.Decode.at ["view", "innerHeight"] int)
    

    但是我已经在本地应用了这些更改以及其他一些更改,我还没有让你的示例工作,仍在尝试,但我目前缺少一些东西。

    备用 Hacky 解决方案。

    • 我尝试了一种快速破解方法,得到了一些可行的方法,但有点笨拙。
    • 我从 StartApp.Simple 切换到 StartApp。
      • 我这样做是为了从 Window.dimensions 添加一个新的输入流。
    • 然后我将 Window.dimension 事件映射到您的调整大小操作。

    这不适用于初始窗口尺寸,但一旦您开始调整大小,它就会起作用。

    module App where
    
    import Effects exposing (Effects, Never)
    import Html exposing (..)
    import Html.Attributes exposing (attribute, class, style, src, width, height)
    import StartApp exposing (start)
    import Window
    
    
    -- MODEL
    type alias Model = 
      { width : Int
      , height : Int
      }
    
    init : (Model, Effects Action)
    init = 
      ( { width = 200
        , height = 200 }
        , Effects.none
      )
    
    -- UPDATE
    type Action = NewSize Int Int
    
    update : Action -> Model -> (Model, Effects Action)
    update (NewSize w h) model = 
      ( { model 
        | width = w
        , height = h 
        }
      , Effects.none
      )
    
    -- VIEW
    
    view : Signal.Address Action -> Model -> Html
    view address model =
      div
        [ class "container" ] -- , onResize address ]
        [ div
          []
          [ img
            [ src "http://package.elm-lang.org/assets/elm_logo.svg"
            , width model.width
            , height model.height
            ]
            []
          ] 
        ]
    
    
    main = 
      app.html
    
    -- APP
    app =
      start
        { init = init
        , update = update
        , view = view 
        , inputs = 
          [
            Signal.map (\(w,h) -> NewSize w h) Window.dimensions
          ]
        }
    
    
    --port tasks : Signal (Task.Task Never ())
    --port tasks =
    --  app.tasks
    

    额外信息。

    http://elm-lang.org/examples 有很多有用的例子。 使用 Window.dimensions http://elm-lang.org/examples/resize-paint 的示例可能会帮助您理解一些事情。

    【讨论】:

    • 谢谢!这很有帮助!我有一个有点相关的设计问题。假设我将这个图像包装在另一个模块中并定义它自己的 newsize 动作。现在我在主模块中导入它,并想使用窗口信号来指定图像的大小。但是由于 image 模块的 newsize 动作没有暴露,我应该如何将这些信息传递给它?
    • 我认为完成本教程可能是您最好的选择。 github.com/evancz/elm-architecture-tutorial。它涵盖了组件以及如何委派东西。作为一项规则,我认为您的所有操作都需要在您的顶层以单一类型访问,并且它会委托操作导致发生的事情。不要忘记投票:)
    猜你喜欢
    • 2013-04-08
    • 2012-02-23
    • 2012-02-15
    • 2023-04-07
    • 1970-01-01
    • 2015-04-20
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多