前言
最近在写一个在线md编辑器,使用的textarea作为文本编辑器,来让用户进行输入;但是textarea并不具备很多日常所见到的编辑器所具备的功能,例如复制剪切光标所在行文本,甚至tab键都会带来一些意外的情况,所以记录一下这些坑。
相关
textarea中tab健失效问题
需求
常见的编辑器中有个功能,是ctrl+c的时候,自动复制/剪切光标所在行的文本。
实现思路
- 获取光标在文本中的位置
- 同时向前向后查找该位置最近的两处的回车换行符位置
- 然后截取这两个换行符之间的文本即可
- 获取位置需要判断一下是不是最后一行,以最后是否有换行符判断即可
-
-
- 将截取的字符串复制到系统的剪切板区域即可
获取光标位置
- 在textarea会有两种移动光标的操作:鼠标、键盘
- 监听这两个事件,然后通过触发事件的对象引用event的selectionStart、selectionEnd获取
- 键盘事件的时候需要注意,每次按键后光标移动了,但是获取到的上次按的位置,需要减一
获取光标位置代码
| <textarea id="editor" cols="30" rows="10"></textarea> <script> editor.addEventListener('keydown', (e) => { let start = e.target.selectionStart let end = e.target.selectionEnd let text=window.getSelection().toString() }) </script>
|
复制文本
- 获取到文本,如上述
- 复制到剪切区,有2中方式,如下:
- document对象的execCommand,是一个函数,参数为对应要操作的指令字符串,如copy;通过他获取input中的选中的文本即可
- Clipboard API的Clipboard,因为第一个操作标准已经放弃,不建议使用;可以使用该操作代替,但是兼容性需要考虑;其次该api必须在用户交互中使用,即不能再页面加载后自动复制粘贴
-
复制文本代码
execCommand
| <input type="text" id="text"> <button id="copy">copy</button> <script> const copy = document.querySelector('#copy') const text = document.querySelector('#text') copy.addEventListener('click', () => { if (!document.execCommand('copy')) throw new Error('不支持改命令') text.select() document.execCommand('copy') console.log('复制成功') }) </script>
|
Clipboard
| <input type="text" id="text"> <button id="copy">copy</button> <script> const copy = document.querySelector('#copy') const text = document.querySelector('#text') copy.addEventListener('click', () => { navigator.clipboard.writeText(text.value) }) </script>
|
复制光标所在行代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <textarea id="editor" cols="30" rows="10"></textarea> <script> const editor = document.querySelector('#editor') function copyText(text) { const input = document.createElement('input'); document.body.appendChild(input); input.setAttribute('value', text); input.setAttribute('id', 'copy'); input.select(); if (document.execCommand('copy')) { document.execCommand('copy'); console.log('复制成功'); } document.body.removeChild(document.querySelector('#copy')) } editor.addEventListener('keydown', (e) => { let isCtrl = e.ctrlKey let code = e.keyCode if (isCtrl && code === 67) { let start = e.target.selectionStart - 1 let end = e.target.selectionEnd - 1 let text = editor.value let left = -1, right = -1 for (let i = start; i >= 0; i--) { if (text[i] === '\n' || i === 0) { left = i break } } for (let i = end; i < text.length; i++) { if (text[i] === '\n' || i === text.length - 1) { right = i break } } let selected = text.substring(left === 0 ? left : left + 1, right === text.length - 1 ? right + 1 : right) if (document.execCommand('copy')) { copyText(selected) } } }) </script>
|