20.30日30日目:ブラウザの幅と高さを得る
今日、私は何か視覚的なことをしたかったですが、私はSVGは利用可能なスペースを埋めるためにしたかった.
代わりに、ブラウザの幅と高さについての情報を得ることを学ぶ日になりました.
JavaScriptでは、私は
innerWidth
and innerHeight
. elmでは、それはより難しいです.このポストには混乱と眠れない眠りが書かれている.
コードデモhttps://ellie-app.com/bZDy65SqXXFa1
目次
3. The code
ブラウザの幅と高さを取得する
ELM文書の経験は少しイライラしました.説明はしばしば良いです、そして、タイプ注釈は助けます、しかし、ちょうど1か2つのコード例が多くを助けたいくつかの場面がありました.
例えば、Browser.Dom.getViewport 良い音が、どのように私はそれを使用しますか?そのタイプ注釈は言う
Task x Viewport
. 見たTask
前述のViewport
よく説明されていますが、地球上ではどうですかx
?もちろん、私はもっと徹底的にドキュメンテーションを読むべきでした、しかし、ちょうど実用的な例を持っていることはどんなレベルの開発者のためにでもよかったでしょう.
type aliasは分かりやすいです.
type alias Viewport =
{ scene :
{ width : Float
, height : Float
}
, viewport :
{ x : Float
, y : Float
, width : Float
, height : Float
}
}
しかし、戻そうとするときBrowser.Dom.getViewport.scene
関数で、このエラーを取得します.This is not a record, so it has no fields to access!
23| Browser.Dom.getViewport.scene
^^^^^^^^^^^^^^^^^^^^^^^
ThisgetViewport
value is a:
Task.Task x Browser.Dom.Viewport
But I need a record with a scene field!
タイプエイリアスを読んでくれたことをよくお詫びします.
だから私は読んでTask documentation , そして、時間の例を再訪してください
Task.perform GetBrowserDimensions Browser.Dom.getViewport
, 次のコードを使用します.type Msg
= GetBrowserDimensions
dimensions =
Task.perform GetBrowserDimensions Browser.Dom.getViewport
これは私が以前見た一種のエラーメッセージをもたらしました、しかし、私はまだ少し苦労します.Msg
and msg
- 良い選択肢はありません.28| Task.perform GetBrowserDimensions Browser.Dom.getViewport
^^^^^^^^^^^^^^^^^^^^
ThisGetBrowserDimensions
value is a:
Msg
Butperform
needs the 1st argument to be:
a -> msg
私はエルムスラックチャンネルで尋ねました.
Samuel Kacer 28 minutes ago
The first argument to Task.perform needs to be a function that will take the result from the Task and wrap it in some kind of message. so for the case of getViewPort, the argument needs to be of type Viewport -> Msg.
the first argument you are providing,GetBrowserDimensions
, is of type Msg, so I assume it doesn't contain anything and has a definition something like this:
type Msg =
...
| GetBrowserDimensions
but instead needs to be something like
| GetBrowserDimensions Viewport
that way the constructor for that message variant will have a type of Viewport -> Msg, which would fit for the Task you are wanting to performarkham 27 minutes ago
you can check out this ellie https://ellie-app.com/bZvHnKqpPrCa1
また、私は窓のリサイズイベントに反応するためにそれを必要としましたonResize documentation 用途
Cmd Msg
そのタイプとして、私は明らかに私はSub Msg
私の場合はKristian Pedersen 2 hours ago
ウィンドウリサイズイベントに対する応答
Actually, I realized I wanted it to update on window resize. Again, I think I’m almost there, but it’s telling me I need a sub msg, not a cmd msg:
https://ellie-app.com/bZBqjmgPS9pa1
What also confuses me is that going by the documentation, the subscriptions function returns a cmd msg, but in my example, it need to be a sub msg: https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResizearkham 1 hour ago
hey Pedersen, it’s just the type of the subscription is a Sub Msg instead of a Cmd Msg , so your subscriptions function should be a Sub Msg, here’s a working ellie https://ellie-app.com/bZC6k6dv9wna1arkham 1 hour ago
I also converted the Ints to Floats to get the type checker to be happyarkham 1 hour ago
and here’s a very simple example of a subscription: https://guide.elm-lang.org/effects/time.htmlarkham 1 hour ago
oh, and to be clear: the documentation is saying that onResize returns a Sub msg https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onResize
助けと忍耐のおかげで、アーカム!あなたは伝説です.
3 .コード
すべての混乱と前後に行くと、私の結果コードは、ほとんどかなり正直に見えるように見える.
3.1 .モデルとMSG
type alias Model =
{ width : Float, height : Float }
initialModel : Model
initialModel =
{ width = 0, height = 0 }
type Msg
= NoOp
| GotInitialViewport Viewport
| Resize ( Float, Float )
モデルはまっすぐ進む.Although GotInitialViewport
and Resize
別の、彼らは両方Float
s.私は、これがどのように見えるか本当に好きでありません.多分それはちょうどそれを介して行うにはクリーナーされているだろうか?
3.2 .メインとサブスクリプション
main : Program () Model Msg
main =
let
handleResult v =
case v of
Err err ->
NoOp
Ok vp ->
GotInitialViewport vp
in
Browser.element
{ init = \_ -> ( initialModel, Task.attempt handleResult Browser.Dom.getViewport )
, view = view
, update = update
, subscriptions = subscriptions
}
subscriptions : model -> Sub Msg
subscriptions _ =
E.onResize (\w h -> Resize ( toFloat w, toFloat h ))
それは私が前に見たことと比較してかなりちゃんとした主な機能です.タスク
handleResult
されて、それはそれらの2つの1つを返しますCmd Msg
年代のslet
文.3.3 .更新
setCurrentDimensions model ( w, h ) =
{ model | width = w, height = h }
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
GotInitialViewport vp ->
( setCurrentDimensions model ( vp.scene.width, vp.scene.height ), Cmd.none )
Resize ( w, h ) ->
( setCurrentDimensions model ( w, h ), Cmd.none )
NoOp ->
( model, Cmd.none )
Cmd.none
しかし、私はエルムが私が慣れているより多くの説明を好むことを推測するけれども、それは代わりに暗黙的でありえました.それは初心者として私に少し余分なオーバーヘッドを加えます、しかし、私はそれが見ることができると思います
Cmd.none
一目で.再び、私は私のダブルアプローチが好きではありません、そこで、私は幅と高さ2つの異なる方法を得ます
vp
変数、および( w, h )
タプル.それはちょうど間違って感じている.3.4 .ビュー
いくつかのデータを表示するだけです.混乱した日への良い結末
view : Model -> Html Msg
view model =
div []
[ text
("The width is "
++ (model.width |> String.fromFloat)
++ "px, and the height is "
++ (model.height |> String.fromFloat)
++ "px"
)
]
結論
これは、JavaScript相互運用を通して行うよりも、elmのやり方ですぐに利点を見ることができない場合です
window.eventListener
.私は間違いなく再読み込みする必要がありますBrowser.Dom and Task ドキュメント.
私も必要なのは良い夜の睡眠です.(お勧めいたします"Why We Sleep" by Matthew Walker )
私はあまりにも早く目を覚まし、シエスタを持っていなかったと私は私の思考と気分に負の影響に気づいている.私は前に学習フラストレーションを介してされているので、同様にこの1つを取得します.
あまりにも良い夜の睡眠を取得し、明日参照してください!
Reference
この問題について(20.30日30日目:ブラウザの幅と高さを得る), 我々は、より多くの情報をここで見つけました https://dev.to/kristianpedersen/30daysofelm-day-20-getting-browser-width-and-height-1nf9テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol