gpt4 book ai didi

textarea - Elm - textarea 选择范围消失

转载 作者:行者123 更新时间:2023-12-04 12:01:27 26 4
gpt4 key购买 nike

我实现了一个 <textarea>在 Elm 中,选项卡缩进和取消缩进,而不是将焦点转移到另一个 HTML 元素。效果很好,除了取消缩进有时会导致选择消失!如果我选择第 5 个字符到第 12 个字符,我按 shift-tab,然后它会删除 2 个制表符,但它也会使选择更改为位置 10 处的光标。选择范围应保持不变..

我在 Ellie 有一个 SSCCE:https://ellie-app.com/3x2qQdLqpHga1/2

以下是一些屏幕截图来说明问题。按设置显示:

Text setup

然后按 Unindent 应该显示以下内容(“def\ng”的选择仍然完好无损):

Unindented with selection still intact

不幸的是,按 Unindent 实际上显示如下。文本没有缩进很好,但选择范围消失了,在 g 之间只有一个光标。和 h :

Unindented without selection

最佳答案

有趣的问题和出色的问题说明!

问题是,由于某种原因,当 selectionStart/selectionEnd 属性之一保持不变时,不会发生重新渲染。尝试在第 42 行将 5 更改为 6。

当您在元素结构中引入强制回流时,它会起作用。看这里:https://ellie-app.com/6Q7h7Lm9XRya1 (我将其更新为 0.19 以查看是否可以解决问题,但没有解决)。

请注意,这可能会重新渲染整个 textarea,因此如果 textarea 是一大段代码,则可能会导致问题。您可以通过在两个相同的 textarea 之间交替来解决这个问题,您可以在每次渲染时切换它们的可见性。

module Main exposing (Model, Msg(..), main, update, view)

-- Note: this is Elm 0.19

import Browser
import Browser.Dom exposing (focus)
import Html exposing (Html, button, div, text, textarea)
import Html.Attributes exposing (attribute, class, cols, id, property, rows, style, value)
import Html.Events exposing (onClick)
import Html.Lazy exposing (lazy2)
import Json.Encode as Encode
import Task exposing (attempt)


type alias Model =
{ content : String
, selectionStart : Int
, selectionEnd : Int
-- keep counter of renderings for purposes of randomness in rendering loop
, renderCounter : Int
}


main =
Browser.element
{ init = initModel
, view = view
, update = update
, subscriptions = \s -> Sub.none
}


initModel : () -> ( Model, Cmd Msg )
initModel flags =
( Model "" 0 0 0, Cmd.batch [] )


type Msg
= Setup
| Unindent
| NoOp (Result Browser.Dom.Error ())


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
let
newRenderCounter =
model.renderCounter + 1

in
case msg of
Setup ->
( { model
| content = "\tabc\n\tdef\n\tghi"
, selectionStart = 5
, selectionEnd = 12
, renderCounter = newRenderCounter
}
, attempt NoOp <| focus "ta"
)

Unindent ->
( { model
| content = "\tabc\ndef\nghi"
, selectionStart = 5
, selectionEnd = 10
, renderCounter = newRenderCounter
}
, attempt NoOp <| focus "ta"
)

NoOp _ ->
( model, Cmd.batch [] )


view : Model -> Html Msg
view model =
div []
(viewTextarea model model.renderCounter
++ [ button [ onClick Setup ] [ text "Setup" ]
, button [ onClick Unindent ] [ text "Unindent" ]
]
)


viewTextarea : Model -> Int -> List (Html msg)
viewTextarea model counter =
let

rerenderForcer =
div [attribute "style" "display: none;"] []

ta =
textarea
[ id "ta"
, cols 40
, rows 20
, value model.content
, property "selectionStart" <| Encode.int model.selectionStart
, property "selectionEnd" <| Encode.int model.selectionEnd
]
[]
in

-- this is the clue. by alternating this every render, it seems to force Elm to render the textarea anew, fixing the issue. Probably not very performant though. For a performant version, use an identical textarea instead of the div and make sure the two selectionStart/end properties both differ from the previous iteration. Then alternate visibility between the two every iteration.
if isEven counter then
[ ta, rerenderForcer ]

else
[ rerenderForcer, ta ]


isEven : Int -> Bool
isEven i =
modBy 2 i == 0

关于textarea - Elm - textarea 选择范围消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44665385/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com