点击按钮复制

JS部分

位置:./themes/YourThemeName/static/clipboard.js

 1// buttons
 2const svgCopy =
 3  '<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg>';
 4const svgCheck =
 5  '<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>';
 6// add button function
 7const addCopyButtons = (clipboard) => {
 8    // 1. Look for pre > code elements in the DOM
 9    document.querySelectorAll("pre > code").forEach((codeBlock) => {
10      // 2. Create a button that will trigger a copy operation
11      const button = document.createElement("button");
12      button.className = "copy-code-button";
13      button.type = "button";
14      button.title = "Copy";
15      button.innerHTML = svgCopy;
16      button.addEventListener("click", () => {
17        clipboard.writeText(codeBlock.innerText).then(
18          () => {
19            button.blur();
20            button.innerHTML = svgCheck;
21            setTimeout(() => (button.innerHTML = svgCopy), 2000);
22          },
23          (error) => (button.innerHTML = "Error")
24        );
25      });
26      // 3. Append the button after the pre tag (.highlight > pre > button > code)
27      const pre = codeBlock.parentNode;
28      pre.parentNode.insertBefore(button, pre.nextSibling);
29      // 4. Listen to keyboard press
30      const highlight = pre.parentNode;
31      highlight.addEventListener('keydown', function(event) {
32        if (
33          event.key === " " ||
34          event.key === "Spacebar" ||
35          event.code === "Space" ||
36          event.key === "Enter" ||
37          event.code === "Enter"
38        ) {
39          clipboard.writeText(codeBlock.innerText).then(
40            () => {
41              button.blur();
42              button.innerHTML = svgCheck;
43              setTimeout(() => (button.innerHTML = svgCopy), 2000);
44            },
45            (error) => (button.innerHTML = "Error")
46          );
47        }
48      });
49    });
50  };
51// trigger function
52if (navigator && navigator.clipboard) {
53  addCopyButtons(navigator.clipboard);
54} else {
55  const script = document.createElement("script");
56  script.src =
57    "https://cdnjs.cloudflare.com/ajax/libs/clipboard-polyfill/3.0.3/promise/clipboard-polyfill.promise.min.js";
58  script.integrity = "sha512-O9Q+AhI1w7LT1/tHysPWDwwrgB1fKJ/nXPNLC30i8LF6RdSz4dGZyWB9WySag3DZMdGuK5yHJEdKXMKI2m5uSQ==";
59  script.crossOrigin = "anonymous";
60  script.referrerpolicy = "no-referrer";
61  script.onload = () => addCopyButtons(clipboard);
62  document.body.appendChild(script);
63}

Hugo处理部分

位置:./themes/YourThemeName/layouts/partials/footer.html

1{{ if (findRE "<code" .Content 1) }}
2    <script src="{{"/js/clipboard.js" | relURL}}"></script>
3{{ end }}

CSS部分

 1.highlight {
 2    position: relative;
 3  }
 4  .copy-code-button {
 5    color: var(--white);
 6    background-color: rgba(255,255,255,50%);
 7    border: none;
 8    border-radius: 6px;
 9    padding: 5px;
10    font-size: 1rem;
11    position: absolute;
12    z-index: 1;
13    right: 0;
14    top: 0;
15    margin: 10px;
16    transition: .1s;
17    opacity: 0.5;
18  }
19  .copy-code-button > svg {
20    fill: var(--white);
21  }
22  .copy-code-button:hover,
23  .copy-code-button:focus,
24  pre:active ~ .copy-code-button,
25  pre:focus ~ .copy-code-button,
26  div.highlight:active > .copy-code-button,
27  div.highlight:focus > .copy-code-button {
28    cursor: pointer;
29    opacity: 1;
30  }

点击代码块复制

JS部分

位置:./themes/YourThemeName/assets/clipboard.js

 1(function () {
 2  function select(element) {
 3    const selection = window.getSelection();
 4
 5    const range = document.createRange();
 6    range.selectNodeContents(element);
 7
 8    selection.removeAllRanges();
 9    selection.addRange(range);
10  }
11
12  document.querySelectorAll("pre code").forEach(code => {
13    code.addEventListener("click", function (event) {
14      if (window.getSelection().toString()) {
15        return;
16      }
17      select(code.parentElement);
18
19      if (navigator.clipboard) {
20        navigator.clipboard.writeText(code.parentElement.textContent);
21      }
22    });
23  });
24})();

Hugo处理部分

位置:./themes/YourThemeName/layouts/partials/footer.html

1{{ $script := resources.Get "clipboard.js" | resources.Minify }}
2{{ with $script.Content }}
3  <script>{{ . | safeJS }}</script>
4{{ end }}