
使用以下两个api
MDN Selection APIMDN Range API
需要 API
const Range = useCallback(() => {
const selObj = window.getSelection();
if (!selObj) return;
return selObj.getRangeAt(0);
}, []);
删除代码
const range = Range();
if (!range) return;
range.deleteContents();// 删除节点
加粗功能代码(修改 加入markdown 语法 ** ** 加粗)
onClick={() => {
const range = Range();
if (!range) return;
const t = document.createElement(“span”);
range.surroundContents(t);//标签先加入 然后在改值
t.innerHTML = `**${range.toString()}**`;
}}
如果选中的文字不是同一行(不是同一个元素)需要先删除原来的 再添加新的
const range = Range();
if (!range) return;
const prev = range.toString();
range.deleteContents();
const t = document.createElement(“span”);
range.surroundContents(t);
t.innerHTML = `**${prev}**`;
完整代码 仅供参考
import { Button } from "antd";
import { useState, useCallback, useRef, useMemo } from "react";
import { FC, ReactElement } from "react";
import styled from "styled-components";
import MarkDown from "../components/MD/MarkDown";
interface IProps {}
const MD: FC = (): ReactElement => {
const [content, setContent] = useState("");
const input = useRef(null);
const inputEvent = useMemo(() => {
const event = document.createEvent("HTMLEvents");
event.initEvent("input", true, true);
return event;
}, []);
const Range = useCallback(() => {
const selObj = window.getSelection();
if (!selObj) return;
return selObj.getRangeAt(0);
}, []);
const onInput = useCallback(e => {
setContent(e.target.innerText);
}, []);
const forceInput = useCallback(() => {
input.current?.dispatchEvent(inputEvent);
}, [inputEvent]);
return (
);
};
export default MD;
const Container = styled.div`
display: flex;
flex-direction: column;
width: 100vw;
height: 100vh;
`;
const Nav = styled.nav`
width: 100%;
height: 50px;
background-color: #000;
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 1;
`;
const EditWrapper = styled.div`
height: calc(100% - 50px);
width: 100%;
display: flex;
& > div {
width: 50%;
max-width: 50%;
padding: 0 5px;
}
& > div:first-child {
border-right: 1px dashed #ccc;
outline: none;
}
`;