【问题标题】:Cursor position lost when updating contenteditable div in Elm在 Elm 中更新 contenteditable div 时光标位置丢失
【发布时间】:2019-01-25 10:44:03
【问题描述】:

在输入内容可编辑的 div 时,如何让光标保持在正确的位置?

我正在使用 Elm 创建一个文本框,我需要在每个输入时处理框中的文本。使用 contenteditable div 而不是 textarea 的原因是我需要能够识别某些单词并在您键入时将它们变成可点击的链接。

问题是当文本更新时,光标会回到文本的开头,所以所有内容都是从后到前输入的。

这是一个演示问题的最小示例:

module Main exposing (..)

import Html
import Html.Events as Hev
import Html.Attributes as Hat
import Json.Decode as Json

main : Program Never Model Msg
main =
    Html.beginnerProgram
        { model = ""
        , update = update
        , view = view
        }

type Msg = NewText String

type alias Model = String

view : Model -> Html.Html Msg
view model =
    Html.div
        [ Hat.contenteditable True
        , Hev.on "input" (Json.map NewText targetTextContent)
        , Hat.style
            [ ("border", "1px solid darkgray") ]
        ]
        [ Html.text model
        ]

targetTextContent : Json.Decoder String
targetTextContent =
    Json.at ["target", "innerText"] Json.string

update : Msg -> Model -> Model
update msg model =
    case msg of
        NewText text -> text

【问题讨论】:

  • 您可能需要自己维护光标的位置,这听起来可能比实际复杂。这个项目做了类似的事情来跟踪光标和选择:Janiczek's elm-editor

标签: html contenteditable elm


【解决方案1】:

这似乎与这里的问题非常相似:Elm - textarea selection range disappearing

问题是当 Elm diff 并重新渲染视图时,浏览器没有重新渲染更改后的 selection 属性,从而保留 HTML。我在那里解决了这个问题,使用一种在每次迭代时重排内容的技巧,从而强制元素实际重新渲染,并正确应用选择属性。

在模型中放置一个计数器,并在每次渲染视图时增加它。然后在文本框元素前面交替插入一个空 div。 (if i % 2 == 0 ...)

【讨论】:

    猜你喜欢
    • 2017-09-17
    • 2011-02-21
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    相关资源
    最近更新 更多