实现类似chat-gpt的复制功能

51 阅读3分钟

前言

最近做内部gpt需要复制答案的功能。

在此记录一下碰到的坑。

问题

复制功能还是比较简单的,通过 document.execCommand("copy"); 就可以实现。

问题有两点:

  1. 答案内容是经过富文本转义后的html代码。

image.png

  1. 正常用新建input元素复制粘贴后文本格式全乱了。

解决

问题一:解决方法很简单,直接采取复制粘贴最外层元素的innerText。

问题二:解决方法是新建一个div元素,然后将其作为文本粘贴的选择范围,具体看代码就知道了。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>复制demo</title>
  </head>
  <body>
    <div class="text-box">
      <p>
        当然,下面是一个关于"冒泡排序"的Java实现示例,简单明了,带着互动和教学性质,以帮助你理解和学习:
      </p>
      <hr />
      <p>
        【引言】<br />
        嘿,小伙伴们!你们是否还记得那些年在编程课上第一次接触的"冒泡排序"?它就像一场欢快的泡泡游戏,一层一层地把数据从混乱变得有序。今天,我们就来一场"Java版冒泡大冒险",一起重温这个经典算法吧!🚀
      </p>
      <hr />
      <p><strong>主体部分:</strong></p>
      <ol>
        <li>
          <p><strong>初识冒泡</strong></p>
          <ul>
            <li>
              提问:你知道什么是冒泡排序吗?它就像洗牌游戏,每轮能自动将大的元素“冒”到序列前端,对吗?
            </li>
          </ul>
        </li>
        <li>
          <p><strong>算法原理</strong></p>
          <ul>
            <li>
              解释:简单来说,冒泡排序就是逐个比较相邻的元素,如果顺序不对就交换,直到没有元素再交换位置,也就是“冒”出了序列的顶部。
            </li>
          </ul>
        </li>
        <li>
          <p><strong>Java实现</strong></p>
          <ul>
            <li>示例:</li>
          </ul>
          <pre><code class="language-java">public class BubbleSortExample {
          public static void bubbleSort(int[] arr) {
              boolean swapped;
              for (int i = 0; i &lt; arr.length - 1; i++) { // 遍历所有元素
                  swapped = false; // 每轮开始,假设没有交换发生
                  for (int j = 0; j &lt; arr.length - 1 - i; // 从0到倒数第二个位置
                      // 假设前i个是有序的,剩下的则需要比较
                      if (arr[j] &gt; arr[j + 1]) { // 如果相邻元素不等,交换它们
                          int temp = arr[j];
                          arr[j] = arr[j + 1];
                          arr[j + 1] = temp;
                          swapped = true; // 某处发生了交换
                      }
                  }
                  // 如果一轮下来没有交换,说明已经有序,可以提前结束
                  if (!swapped) break;
              }
          }
          // 测试部分,你可以尝试给一个数组,看看排序效果
          public static void main(String[] args) {
              int[] unsortedArray = {5, 3, 8, 1, 9, 2}; // 你的测试数组
              bubbleSort(unsortedArray);
              // 输出排序结果
              for (int num : unsortedArray) {
                  System.out.println(num);
              }
          }
      }
      </code></pre>
        </li>
        <li>
          <p><strong>实战环节</strong></p>
          <ul>
            <li>
              提问:你有心爱的乱序数组想要挑战吗?试着将下面的数组输入到<code>main</code>方法里,让我们一起见证冒泡排序的魔法吧!
            </li>
          </ul>
        </li>
        <li>
          <p><strong>优化与思考</strong></p>
          <ul>
            <li>
              谈谈:冒泡排序虽然效率不高,但算法简单易懂。你有没有想过如何改进它,比如在数据已经基本有序的情况下提前结束排序?
            </li>
          </ul>
        </li>
      </ol>
      <hr />
      <p>
        <strong>结尾总结</strong><br />
        亲爱的朋友们,冒泡排序不仅帮我们学习了基本排序概念,更是锻炼了我们的逻辑思维。感谢你们的陪伴,希望你们在享受这个过程的同时,也对排序有了更深的理解。下次再遇到乱七八糟的数据,记得它就在那里,静静的“冒”出来,等待我们去整理。🎉
      </p>
      <hr />
      <p>
        接下来,你可以扫描下方二维码,预约一份实践任务,让我们一起动手实践,用Java的智慧给数据穿上有序的新衣!二维码——(提供二维码链接)
      </p>
      <hr />
      <p>
        请记得,编程的乐趣就在于这个过程中,无论是问题的提出,还是解答的探索,都是学习和成长的过程。快去体验吧!😉
      </p>
    </div>
    <button onclick="copyText(text.innerText)">复制</button>
    <script>
      const text = document.querySelector(".text-box");
      // 复制内容到剪贴板
      function copyText(text) {
        const new_input = document.createElement("div");
        new_input.style.position = "fixed";
        new_input.style.top = "0";
        new_input.style.left = "0";
        new_input.style.opacity = "0";
        new_input.style.zIndex = "999";
        document.body.appendChild(new_input);
        new_input.innerText = text;
        // 创建一个新的文本范围
        const range = document.createRange();
        range.selectNode(new_input);
        // 移除所有之前选择的文本范围
        window.getSelection().removeAllRanges();
        // 添加新的文本范围
        window.getSelection().addRange(range);
        document.execCommand("copy");
        // 移除所有选择的文本范围
        window.getSelection().removeAllRanges();
        document.body.removeChild(new_input);
        alert("复制成功");
      }
    </script>
  </body>
</html>