Положение курсора потеряно при обновлении contenteditable div в Elm

Как я могу сохранить курсор в нужном месте при вводе содержимого 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

Возможно, вам придется самостоятельно поддерживать положение курсора, что может показаться более сложным, чем есть на самом деле. Этот проект проделал похожую вещь для отслеживания курсора и выделения: Вяз-редактор Яничека

Tomáš Zemanovič 19.08.2018 06:13
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
4
1
347
1

Ответы 1

Это похоже на проблему здесь: Вяз - исчезновение диапазона выделения текстового поля

Проблема заключалась в том, что измененное свойство выбора не отображалось повторно браузером, когда Элм сравнивал и повторно отображал представление, сохраняя HTML. Я решил это там, используя хак, который перекомпоновывает контент на каждой итерации, тем самым заставляя элементы фактически повторно отрисовываться, а свойство selection применять правильно.

Поместите счетчик в свою модель и увеличивайте его каждый раз при визуализации вида. Затем поочередно вставляйте пустой div перед элементом текстового поля. (if i % 2 == 0 ...)

Другие вопросы по теме