js 进行在线编辑器开发
2023年5月16日 01:36
编程技术
js 进行在线编辑器开发
基于 textarea 开发的 markdown 编辑器
textarea 最简单,但是可以编辑的内容也少。
需要的了解的知识
const element: HTMLTextAreaElement;
element.selectionStart // 获取或设置选中的起始位置
element.selectionEnd // 获取或设置选中的结束位置
// 获取选中的文字
const v = element.value;
const selectValue = v.substring(element.selectionStart, element.selectionEnd);
// 替换选中的内容
const replace = '';
element.value = v.substring(0, element.selectionStart) + replace + v.substring(element.selectionEnd);
// 移动光标到指定位置,移动光标到开始位置
element.selectionStart = 0 
element.selectionEnd = 0
// 移动光标到结尾
element.selectionStart = element.value.length
element.selectionEnd = element.value.length
// 需要把焦点设置到元素,才会显示光标
element.focus();
textarea 只接受字符串,所以图片,超链接等需要使用 markdown 格式转成对应的字符串
基于 div 开发的 富文本编辑器
把div 设置为可编辑模式
<div contentEditable="true"></div>
需要了解的知识
- 默认换行是自动添加 '<div><br></div>'
 - 获取选中
 
const element: HTMLDivElement;
const sel = window.getSelection();
const range = sel.getRangeAt(0); 
// range 就是当前选中的内容了
range.startContainer // 选中的起始节点
range.startOffset   // 在起始节点的具体位置
range.endContainer  // 选中的结束节点
range.startOffset   // 在结束节点的具体位置
// 当未选中任何内容时
range.startContainer === range.endContainer && range.startOffset === range.endOffset
range.startContainer // 节点的类型,有 Text 、HtmlElement
range.startOffset  // 当 节点类型为 Text 时,则为字符串的位置, 当为 HtmlElement 时,则为在节点中子元素的位置, 例如0 则是元素的最前面
// 选中 区域
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(selectRange);
// 选中指定元素
const selectRange = document.createRange();
// 选中整个元素
selectRange.selectNodeContents(element);
// 选中元素的一部分
selectRange.setStart(element, 0);
selectRange.setEnd(element, 0);
sel.removeAllRanges();
sel.addRange(selectRange);
// 截断字符串节点
const node: Text
node.splitText(offset) // 返回新创建的后一部分字符串的节点, 自动会添加到页面上的
基于 div 开发的 代码编辑器
相对来说,代码编辑器相对简单,就只要 显示对应行号、对部分字符串加样式即可,当然更高级的需要加代码提示候选就更复杂点了。
const element: HtmlDivElement;
element.contentEditable = 'true';
基本逻辑
- 对回车进行换行处理,实际就是在选择的地方切断,把后面一部分放到另一行
 - 新增行,需要同时增加行号,及在行号列表中增加新的一行,并同时个更新后面的行号
 - 对行的高度要跟行号的高度进行同步
 - 缩进或者文字输入需要提取整行内容进行处理
 
let isComposition = false; // 判断是否是输入法输入
element.addEventListener('keydown', e => {...剩余内容已隐藏
查看完整文章以阅读更多