code block script copy buttons

Added copy to clipboard buttons for easier grabbing of the code provided in my blog posts, or anywhere else on the website. As long as there is text inside a code block, a copy button is added to it. It checks if the first line of code is not a descriptor, as I use them - such as “CSS:”, “HTML:”, or “JAVASCRIPT:”. After excluding the descriptor if present, it copies the contents of the code block to clipboard. The buttons are not displayed on mobile. The check to see if the code block actually contains text excludes normal code blocks which do not display the source code from having buttons, as well as code blocks which contain only a descriptor.

HTML:

JAVASCRIPT:

<script>
document.addEventListener('DOMContentLoaded', function () {
// Mobile check
const headerActions = document.querySelector('.header-actions');
let isTouch = false;
function checkHeader() {
const styles = window.getComputedStyle(headerActions);
isTouch = styles.getPropertyValue('display') !== 'flex';
}
checkHeader();
if (isTouch === false) {
//initialize popover
let hideTimeout;
var popover = document.getElementById('custom-popover');
var popoverMessage = document.getElementById('popover-message');
function showPopover(message) {
popoverMessage.textContent = message;
popover.classList.add('show');
popover.style.pointerEvents = 'auto';
clearTimeout(hideTimeout);
hideTimeout = setTimeout(function() {
popover.classList.remove('show');
popover.style.pointerEvents = 'none';
}, 3000);
}
//add the copy buttons
const codeBlocks = document.querySelectorAll('.code-block');
codeBlocks.forEach(function (block) {
let codeText;
// Get the inner text and check if it's not empty
const codeLines = block.innerText.split('\n');
if (codeLines.length > 0 && (codeLines[0].trim() === 'HTML:' || codeLines[0].trim() === 'JAVASCRIPT:' || codeLines[0].trim() === 'CSS:')) {
codeText = codeLines.slice(1).join('\n');
} else {
codeText = block.innerText; 
}
// Check if codeText is not empty before adding the copy button
if (codeText.trim() !== '') {
const copyButton = document.createElement('div');
copyButton.classList.add('codeBlockCopyBtn');
copyButton.addEventListener('click', function () {
// Check if codeText is not empty before copying
if (codeText.trim() !== '') {
navigator.clipboard.writeText(codeText).then(function() {
$('#popoverMessage').off('click');
popoverMessage.style.color = "#ffc700";
showPopover('Code copied');
}).catch(function(err) {
$('#popoverMessage').off('click');
popoverMessage.style.color = "#ea4b1a";
showPopover('Failed to copy code');
});
} else {
popoverMessage.style.color = "#ea4b1a";
showPopover('No code to copy');
}
});
block.appendChild(copyButton);
}
});
}
});
</script>
CSS:

.codeBlockCopyBtn {
  position: absolute;
  top: 45px;
  left: 0;
  margin-left: -50px;
  width: 45px;
  height: 45px;
  cursor: pointer;
  pointer-events: auto;
  background-image: url('https://images.squarespace-cdn.com/content/v1/6654b2fee26f292de13f1a9d/60945976-1d8a-4994-b513-32f2ef4c2269/papericon2.png');
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;  
  transition: all 0.6s ease;
}
.codeBlockCopyBtn:hover {
  transition: all 0.3s ease;
  scale: 1.15;
}
@media only screen and (max-width:790px) {
.codeBlockCopyBtn {
  display: none;
  }
}
Previous
Previous

horoscopes, solar flares, geomagnetic storms, and a dinosaur

Next
Next

Real time geographical dynamic weather effects