[英]Set cursor on new created element doesn't work with empty innerHtml
在上面你可以看到代碼,我試圖讓它工作。 這里的想法是,我有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.