我试图使一个富文本编辑器的React。我卡住了,由于问题。问题是,与每一个字符,我键入的插入点是不与由于这光标被卡住的左边和字符被插入在左边。此外,当我手动移动光标在一个字的末尾,并尝试再次键入它移动到左边。这是我的texteditor的截图(https://i.stack.imgur.com/TnZNT.png)
import React from "react";
import { useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faBold,
faCode,
faFileCode,
faFilm,
faImage,
faItalic,
faLink,
faList,
faListOl,
faQuoteRight,
faStrikethrough,
faUnderline,
} from "@fortawesome/free-solid-svg-icons";
import "./textEditor.css";
const TextEditor = () => {
const [content, setContent] = useState("");
const [isBold, setIsBold] = useState(false);
const [isItalic, setIsItalic] = useState(false);
const [isUnderline, setIsUnderline] = useState(false);
const [isStrikeThrough, setStrikeThrough] = useState(false);
const [isBlockquote, setIsBlockquote] = useState(false);
const [isHeading1, setIsHeading1] = useState(false);
const [isHeading2, setIsHeading2] = useState(false);
const [isOrderedList, setIsOrderedList] = useState(false);
const [isUnorderedList, setIsUnorderedList] = useState(false);
const [isInlineCode, setIsInlineCode] = useState(false);
const [isCodeBlock, setIsCodeBlock] = useState(false);
const handleFormat = (style, value = null) => {
// Toggle the state for the corresponding style
switch (style) {
case "bold":
setIsBold(!isBold);
break;
case "italic":
setIsItalic(!isItalic);
break;
case "underline":
setIsUnderline(!isUnderline);
break;
case "strikeThrough":
setStrikeThrough(!isStrikeThrough);
break;
case "formatBlock":
// Handle specific cases for formatBlock
if (value === "<blockquote>") {
setIsBlockquote(!isBlockquote);
value = isBlockquote ? "<p>" : "<blockquote>";
} else if (value === "<h1>") {
setIsHeading1(!isHeading1);
value = isHeading1 ? "<p>" : "<h1>";
} else if (value === "<h2>") {
setIsHeading2(!isHeading2);
value = isHeading2 ? "<p>" : "<h2>";
} else if (value === "<pre>") {
setIsCodeBlock(!isCodeBlock);
value = isCodeBlock ? "<p>" : "<pre>";
}
break;
case "insertOrderedList":
setIsOrderedList(!isOrderedList);
break;
case "insertUnorderedList":
setIsUnorderedList(!isUnorderedList);
break;
case "code":
setIsInlineCode(!isInlineCode);
break;
case "createLink":
const url = prompt("Enter the link URL:");
document.execCommand("createLink", false, url);
break;
default:
break;
}
// Check the current state before applying the style
document.execCommand(style, false, value);
};
return (
<div className="editor-wrapper">
<div className="editor">
<div className="toolbar">
<button className="editor-btn" onClick={() => handleFormat("bold")}>
<FontAwesomeIcon icon={faBold} />
</button>
<button
className="editor-btn"
onClick={() => handleFormat("underline")}
>
<FontAwesomeIcon icon={faUnderline} />
</button>
<button className="editor-btn" onClick={() => handleFormat("italic")}>
<FontAwesomeIcon icon={faItalic} />
</button>
<button
className="editor-btn"
onClick={() => handleFormat("strikeThrough")}
>
<FontAwesomeIcon icon={faStrikethrough} />
</button>
<button
className="editor-btn"
onClick={() => handleFormat("formatBlock", "<blockquote>")}
>
<FontAwesomeIcon icon={faQuoteRight} />
</button>
<button
className="editor-btn"
style={{ fontWeight: "bold" }}
onClick={() => handleFormat("formatBlock", "<h1>")}
>
H1
</button>
<button
className="editor-btn"
style={{ fontWeight: "bold" }}
onClick={() => handleFormat("formatBlock", "<h2>")}
>
H2
</button>
<button
className="editor-btn"
onClick={() => handleFormat("insertUnorderedList")}
>
<FontAwesomeIcon icon={faList} />
</button>
<button
className="editor-btn"
onClick={() => handleFormat("insertOrderedList")}
>
<FontAwesomeIcon icon={faListOl} />
</button>
<button className="editor-btn" onClick={() => handleFormat("code")}>
<FontAwesomeIcon icon={faCode} />
</button>
<button
className="editor-btn"
onClick={() => handleFormat("formatBlock", "<pre>")}
>
<FontAwesomeIcon icon={faFileCode} />
</button>
<button
className="editor-btn"
onClick={() => handleFormat("createLink")}
>
<FontAwesomeIcon icon={faLink} />
</button>
<button
className="editor-btn"
onClick={() =>
handleFormat("insertImage", prompt("Enter image URL:"))
}
>
<FontAwesomeIcon icon={faImage} />
</button>
<button
className="editor-btn"
onClick={() =>
handleFormat(
"insertHTML",
'<iframe width="560" height="315" src="https://www.youtube.com/embed/VIDEO_ID" frameborder="0" allowfullscreen></iframe>'
)
}
>
<FontAwesomeIcon icon={faFilm} />
</button>
</div>
<div
className="text-editor"
contentEditable="true"
dir="ltr"
dangerouslySetInnerHTML={{ __html: content }}
onInput={(e) => {
setContent(e.target.innerHTML);
e.target.focus();
}}
/>
<br />
</div>
</div>
);
};
export default TextEditor;
字符串
CSS
.editor-wrapper {
width: 100%;
height: 500px;
display: flex;
flex-direction: column;
align-items: center;
}
.editor {
width: 70%;
}
.toolbar {
border: 1px solid black;
}
.text-editor {
border: 1px solid black;
padding-left: 2px;
min-height: 100px;
resize: vertical;
overflow: auto;
}
.editor:focus {
border: none;
}
.editor-btn {
background: none;
border: none;
cursor: pointer;
color: #414141;
}
.editor-btn:hover {
color: blue;
}
.text-editor blockquote {
border-left: 4px solid #414141;
margin-right: 2px;
}
.text-editor pre {
background-color: #dbdbdb;
word-wrap: break-word;
}
.text-editor code {
background-color: #dbdbdb;
}
型
1条答案
按热度按时间7dl7o3gd1#
我解决了这个问题,添加了一个函数来聚焦光标和用户,在内容钩子上有一个监听器,并像这样执行focus函数:
字符串
这是我创建的函数的代码。
型
这里有一个react项目的链接,你的问题已经解决了https://github.com/pablosalazzar/stackoverflow-answer-2