如何强制Elm重用DOM元素?

如何强制Elm重用DOM元素?,elm,Elm,我想使用Elm制作一个web应用程序,该应用程序将包含一些视频元素,具有动态布局,可以根据浏览器的宽度和高度进行更改。当我尝试这样做时,很明显Elm正在为视频生成新的元素,但这不起作用,因为视频元素具有需要保留的状态 为了简单起见,我用计数器而不是视频来演示这个问题。我试图解决Html.lazy和Keyed.node的问题,但问题仍然存在 这里的代码也可以从中克隆 src/Main.elm: port module Main exposing (..) import Browser impor

我想使用Elm制作一个web应用程序,该应用程序将包含一些视频元素,具有动态布局,可以根据浏览器的宽度和高度进行更改。当我尝试这样做时,很明显Elm正在为视频生成新的元素,但这不起作用,因为视频元素具有需要保留的状态

为了简单起见,我用计数器而不是视频来演示这个问题。我试图解决
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频道的杰西塔提出了这个想法