如何强制Elm重用DOM元素?
我想使用Elm制作一个web应用程序,该应用程序将包含一些视频元素,具有动态布局,可以根据浏览器的宽度和高度进行更改。当我尝试这样做时,很明显Elm正在为视频生成新的元素,但这不起作用,因为视频元素具有需要保留的状态 为了简单起见,我用计数器而不是视频来演示这个问题。我试图解决如何强制Elm重用DOM元素?,elm,Elm,我想使用Elm制作一个web应用程序,该应用程序将包含一些视频元素,具有动态布局,可以根据浏览器的宽度和高度进行更改。当我尝试这样做时,很明显Elm正在为视频生成新的元素,但这不起作用,因为视频元素具有需要保留的状态 为了简单起见,我用计数器而不是视频来演示这个问题。我试图解决Html.lazy和Keyed.node的问题,但问题仍然存在 这里的代码也可以从中克隆 src/Main.elm: port module Main exposing (..) import Browser impor
Html.lazy
和Keyed.node
的问题,但问题仍然存在
这里的代码也可以从中克隆
src/Main.elm
:
port module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Attributes as Attribute exposing (id, style)
import Html.Events exposing (onClick)
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
type alias Model =
{ layout : Layout }
type Layout
= Row
| Column
init : () -> ( Model, Cmd Msg )
init _ =
( { layout = Row }, startCounters () )
type Msg
= ToggleLayout
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ToggleLayout ->
let
l2 =
case model.layout of
Row ->
Column
Column ->
Row
in
( { model | layout = l2 }, Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
view : Model -> Html Msg
view model =
div []
[ button [ onClick ToggleLayout ] [ text "Toggle Layout" ]
, counters model
]
counters : Model -> Html Msg
counters model =
case model.layout of
Column ->
div []
[ div [] [ counter1 ]
, div [] [ counter2 ]
]
Row ->
div [] [ counter1, spacer, counter2 ]
spacer : Html Msg
spacer =
text " "
counter1 : Html Msg
counter1 =
span [ id "counter1" ]
[ text "0" ]
counter2 : Html Msg
counter2 =
span [ id "counter2" ]
[ text "0" ]
port startCounters : () -> Cmd msg
static/index.html
:
主要
正文{填充:0;边距:0;}
window.app=Elm.Main.init({node:document.getElementById(“Elm”)});
window.app.ports.startCounters.subscribe(函数(){
设c1=document.getElementById(“计数器1”);
设c2=document.getElementById(“counter2”);
函数增量(e){
设n=parseInt(即innerText);
e、 innerText=n+1;
}
requestAnimationFrame(函数(){
setInterval(函数(){
增量(c1);
增量(c2);
}, 100)
})
});
Makefile
:
static/Main.js: src/Main.elm
elm make src/Main.elm --output=static/Main.js
使元素在DOM树中始终保持相同的深度就是一个窍门 以下是新代码:
counters : Model -> Html Msg
counters model =
let
d =
case model.layout of
Column ->
"column"
Row ->
"row"
in
div
[ style "flex-direction" d
, style "display" "flex"
]
[ counter1
, counter2
]
counter1 : Html Msg
counter1 =
span [ id "counter1", style "padding" "8px" ]
[ text "0" ]
counter2 : Html Msg
counter2 =
span [ id "counter2", style "padding" "8px" ]
[ text "0" ]
port startCounters : () -> Cmd msg
感谢Elm Slack频道的杰西塔提出了这个想法