跳转到内容
返回

textarea中复制光标所在行文本

前言

最近在写一个在线md编辑器,使用的textarea作为文本编辑器,来让用户进行输入;但是textarea并不具备很多日常所见到的编辑器所具备的功能,例如复制剪切光标所在行文本,甚至tab键都会带来一些意外的情况,所以记录一下这些坑。

相关

textarea中tab健失效问题

需求

常见的编辑器中有个功能,是ctrl+c的时候,自动复制/剪切光标所在行的文本。

实现思路

  1. 获取光标在文本中的位置
  2. 同时向前向后查找该位置最近的两处的回车换行符位置
  3. 然后截取这两个换行符之间的文本即可
  1. 将截取的字符串复制到系统的剪切板区域即可

获取光标位置

获取光标位置代码

<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>

复制文本

复制文本代码

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();
    // 执行复制 返回一个Boolean
    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>

复制光标所在行代码

<textarea id="editor" cols="30" rows="10"></textarea>
<script>
  const editor = document.querySelector("#editor");
  // 复制文本 创建input来选中内容
  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 => {
    // 是否是ctrl
    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--) {
        // 0时说明为第一行
        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>


上一篇
记一次跨平台开发
下一篇
北京