Hugo添加代码复制功能
点击按钮复制 #
JS部分 #
位置:./themes/YourThemeName/static/clipboard.js
// buttons
const svgCopy =
'<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>';
const svgCheck =
'<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>';
// add button function
const addCopyButtons = (clipboard) => {
// 1. Look for pre > code elements in the DOM
document.querySelectorAll("pre > code").forEach((codeBlock) => {
// 2. Create a button that will trigger a copy operation
const button = document.createElement("button");
button.className = "copy-code-button";
button.type = "button";
button.title = "Copy";
button.innerHTML = svgCopy;
button.addEventListener("click", () => {
clipboard.writeText(codeBlock.innerText).then(
() => {
button.blur();
button.innerHTML = svgCheck;
setTimeout(() => (button.innerHTML = svgCopy), 2000);
},
(error) => (button.innerHTML = "Error")
);
});
// 3. Append the button after the pre tag (.highlight > pre > button > code)
const pre = codeBlock.parentNode;
pre.parentNode.insertBefore(button, pre.nextSibling);
// 4. Listen to keyboard press
const highlight = pre.parentNode;
highlight.addEventListener('keydown', function(event) {
if (
event.key === " " ||
event.key === "Spacebar" ||
event.code === "Space" ||
event.key === "Enter" ||
event.code === "Enter"
) {
clipboard.writeText(codeBlock.innerText).then(
() => {
button.blur();
button.innerHTML = svgCheck;
setTimeout(() => (button.innerHTML = svgCopy), 2000);
},
(error) => (button.innerHTML = "Error")
);
}
});
});
};
// trigger function
if (navigator && navigator.clipboard) {
addCopyButtons(navigator.clipboard);
} else {
const script = document.createElement("script");
script.src =
"https://cdnjs.cloudflare.com/ajax/libs/clipboard-polyfill/3.0.3/promise/clipboard-polyfill.promise.min.js";
script.integrity = "sha512-O9Q+AhI1w7LT1/tHysPWDwwrgB1fKJ/nXPNLC30i8LF6RdSz4dGZyWB9WySag3DZMdGuK5yHJEdKXMKI2m5uSQ==";
script.crossOrigin = "anonymous";
script.referrerpolicy = "no-referrer";
script.onload = () => addCopyButtons(clipboard);
document.body.appendChild(script);
}
Hugo处理部分 #
位置:./themes/YourThemeName/layouts/partials/footer.html
{{ if (findRE "<code" .Content 1) }}
<script src="{{"/js/clipboard.js" | relURL}}"></script>
{{ end }}
CSS部分 #
.highlight {
position: relative;
}
.copy-code-button {
color: var(--white);
background-color: rgba(255,255,255,50%);
border: none;
border-radius: 6px;
padding: 5px;
font-size: 1rem;
position: absolute;
z-index: 1;
right: 0;
top: 0;
margin: 10px;
transition: .1s;
opacity: 0.5;
}
.copy-code-button > svg {
fill: var(--white);
}
.copy-code-button:hover,
.copy-code-button:focus,
pre:active ~ .copy-code-button,
pre:focus ~ .copy-code-button,
div.highlight:active > .copy-code-button,
div.highlight:focus > .copy-code-button {
cursor: pointer;
opacity: 1;
}
点击代码块复制 #
JS部分 #
位置:./themes/YourThemeName/assets/clipboard.js
(function () {
function select(element) {
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
document.querySelectorAll("pre code").forEach(code => {
code.addEventListener("click", function (event) {
if (window.getSelection().toString()) {
return;
}
select(code.parentElement);
if (navigator.clipboard) {
navigator.clipboard.writeText(code.parentElement.textContent);
}
});
});
})();
Hugo处理部分 #
位置:./themes/YourThemeName/layouts/partials/footer.html
{{ $script := resources.Get "clipboard.js" | resources.Minify }}
{{ with $script.Content }}
<script>{{ . | safeJS }}</script>
{{ end }}