簡體   English   中英

在新創建的元素上設置 cursor 不適用於空的 innerHtml

[英]Set cursor on new created element doesn't work with empty innerHtml

編輯 nameless-feather-duk25

在上面你可以看到代碼,我試圖讓它工作。 這里的想法是,我有contentEditable div 元素,我在其中輸入一些文本,我有按鈕bold ,你可以點擊它,它將在我的div內部創建新strong元素,並將插入符號到這個元素,以提供我有機會輸入這個元素。 似乎它把插入符號放在了這個元素上,但是當我開始輸入時,它輸入了 previos 元素。 我怎樣才能把迎合新創建的元素。 我也在這個元素上創建它,也許有一種方法可以通過 id 來滿足元素? 或任何其他適用於我的情況的解決方案。

import { useEffect, useState, useRef } from "react";

import "./styles.css";

const id = "textarea";

const Buttons = {
  bold: "bold",
  custom: "custom"
};

export default function App() {
  const [button, setButton] = useState();

  const buttons = [
    {
      text: "Bold",
      type: Buttons.bold
    }
  ];

  const onButtonClick = (buttonValue) => {
    if (button === buttonValue) {
      setButton(Buttons.custom);
    } else {
      setButton(buttonValue);
    }
  };

  const prevButton = usePrevious(button);

  useEffect(() => {
    if (prevButton !== button) {
      const element = document.getElementById(id);

      if (element) {
        console.log(element);

        if (button === Buttons.bold) {
          const strong = document.createElement("strong");
          const id = generateUuid();

          strong.id = id;

          element.appendChild(strong);

          const createdEl = document.getElementById(id);

          const range = document.createRange();
          const sel = document.getSelection();

          if (createdEl) {
            console.log(createdEl, "createdEl");
            range.setStart(createdEl, 0);
            range.setEnd(createdEl, 0);
          }

          if (sel) {
            console.log(sel, "sel");
            sel.removeAllRanges();
            sel.addRange(range);
          }
        }
      }
    }
  }, [prevButton, button]);

  return (
    <div>
      <div contentEditable id={id} className="rich-text" />
      {buttons.map((buttonEntity) => {
        return (
          <button onClick={() => onButtonClick(buttonEntity.type)}>
            {buttonEntity.text}
          </button>
        );
      })}
    </div>
  );
}

const usePrevious = (value) => {
  const ref = useRef();

  useEffect(() => {
    ref.current = value;
  }, [value]);

  return ref.current;
};

export const generateUuid = () =>
  Date.now().toString(36) + Math.random().toString(36).substring(2);

useEffect中描述的所有邏輯都通過創建新元素,並迎合該元素。 值得一提的是,如果您將一些innerHtml文本設置為新創建的元素,並將設置

  range.setStart(createdEl, 1);
  range.setEnd(createdEl, 1);

那么它會工作,但如果里面沒有innerHtml ,它就不起作用

contenteditable 的行為很奇怪, element.focus()不能直接工作,但在某些情況下,它與 setTimeout() 一起工作:

const div = document.getElementById('textarea');
setTimeout(() => div.focus(), 0);

您可能希望添加tabindex=0以允許用戶通過鍵盤導航到它。

無論如何,使用可編輯的內容作為完整的編輯器可能會給您帶來不好的體驗,它有點混亂且難以控制。 您可能希望使用隱藏的輸入來執行此操作。

此外,本文檔建議您可以使用可編輯的內容制作富文本編輯器,但它似乎已被棄用 - https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM