개요
이번에 블로그에서 사용하는 코드 블럭에 복사 버튼을 추가해보았다. 다른 글들을 참고하며 작성하고, 원하는대로 수정하여 이미지 버튼으로 만들어 보았다.
clipboard.js
복사 버튼은 cilpboard.js의 기능을 사용해 구현할 수 있는데 파일과 사용법은 다음의 사이트에서 확인 가능하다.
깃허브의 'dist > clipboard.min.js'을 다운로드 받아 티스토리에 업로드해서 사용해도 되고, 'script src'로 불러와서 바로 사용할 수도 있다. 각각 아래의 코드를 html의 <head>와 </head> 사이에 작성해주면 된다.
- 파일 업로드했을 때
<script type="text/javascript" src="./images/clipboard.min.js"></script>
- 바로 사용할 때
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.11/clipboard.min.js" integrity="sha512-7O5pXpc0oCRrxk8RUfDYFgn0nO1t+jLuIOQdOMRp4APB7uZ4vSjspzp5y6YDtDs4VzUSTbWzBFZ/LKJhnyFOKw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
버튼 생성 코드
버튼 생성 코드는 다음과 같이 작성했고, javascript는 html의 <head>에, CSS는 CSS에 작성해주면 복사 버튼을 만들 수 있다.
- javascript
<script type="text/javascript">
window.addEventListener('load', function () {
document.querySelectorAll('pre[id^="code"]').forEach(function (e, index) {
let button = document.createElement('button');
button.className = 'copy-button';
button.style.cursor = 'pointer';
button.setAttribute('data-clipboard-text', e.innerText);
button.addEventListener('mouseleave', function(event) {
event.currentTarget.setAttribute('class', 'copy-button');
});
var copyIcon = Object.assign(document.createElement('img'), { src: './images/copy_clipboard_icon.png', alt: 'Copy Icon' });
button.appendChild(copyIcon);
e.appendChild(button);
});
var clipboard = new ClipboardJS('.copy-button');
clipboard.on('success', function (e) {
var button = e.trigger;
var successIcon = Object.assign(document.createElement('img'), { src: './images/check_clipboard_icon.png', alt: 'Copy Complete Icon' });
var copyIcon = Object.assign(document.createElement('img'), { src: './images/copy_clipboard_icon.png', alt: 'Copy Icon' });
button.innerHTML = '';
button.appendChild(successIcon);
button.setAttribute('class', 'copy-button copy-message');
setTimeout(function() {
button.setAttribute('class', 'copy-button');
button.innerHTML = '';
button.appendChild(copyIcon);
}, 1500);
});
});
</script>
- CSS
pre {
position: relative;
overflow: visible;
}
pre .copy-button {
opacity: 0;
position: absolute;
right: 8px;
top: 8px;
padding: 4px;
background: #2c2d31;
border-radius: 5px;
border-color: #9ca3af;
border-width: 1px;
transition: opacity .3s ease-in-out;
}
pre .copy-button img {
width: 24px;
height: 24px;
vertical-align: middle;
}
pre:hover .copy-button {
opacity: 1;
}
pre .copy-button:hover {
color: #eee;
transition: all ease-in-out 0.3s;
}
pre .copy-button:active {
border-width: 3px;
border-color: #FFA500;
transition: all ease-out 0.1s;
}
.copy-message:before {
font-family: SUIT, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
content: "Copied";
position: absolute;
font-weight: bold;
font-size: 14px;
left: -10px;
bottom: 49px;
padding: 2px;
color: #eee;
background: #2c2d31;
border-radius: 5px;
}
.copy-message:after {
border-top: 8px solid #2c2d31;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 0px solid transparent;
content: "";
position: absolute;
bottom: 41px;
}
이미지 버튼을 만들기 위해서 'check_clipboard_icon.png' 와 'copy_clipboard_icon.png'를 티스토리에 업로드하고 사용했다. 파일은 다음 사이트에서 찾았으며 이 사이트는 아이콘이 필요한 여러 경우에 사용하기 좋다.
코드 설명
혹시나 코드의 동작 원리가 궁금하신 분들을 위해 주석을 작성해보았다. 간단하게 설명하자면 페이지에서 id가 code인 코드 블럭을 모두 찾아 복사 버튼을 만들어 준다. 버튼을 클릭하면 clipboard.js에 의해 텍스트가 복사되며 버튼의 모양이 바뀌는 이벤트를 실행한다.
- javascript
<script type="text/javascript">
window.addEventListener('load', function () {
document.querySelectorAll('pre[id^="code"]').forEach(function (e, index) { // 모든 코드 블록에 대해 반복
let button = document.createElement('button'); // 복사 버튼 생성
button.className = 'copy-button'; // 클래스 지정
button.style.cursor = 'pointer'; // 커서 스타일 지정
button.setAttribute('data-clipboard-text', e.innerText); // 클립보드에 복사할 텍스트 지정
button.addEventListener('mouseleave', function(event) { // 마우스가 버튼을 떠날 때 이벤트 처리
event.currentTarget.setAttribute('class', 'copy-button'); // 'copy-message' 제거
});
// 복사 아이콘 생성 및 버튼에 추가
var copyIcon = Object.assign(document.createElement('img'), { src: './images/copy_clipboard_icon.png', alt: 'Copy Icon' });
button.appendChild(copyIcon);
e.appendChild(button); // 복사 버튼을 코드 블록에 추가
});
// ClipboardJS를 사용하여 클립보드 이벤트 처리
var clipboard = new ClipboardJS('.copy-button');
clipboard.on('success', function (e) {
var button = e.trigger;
// 복사 성공 아이콘 생성
var successIcon = Object.assign(document.createElement('img'), { src: './images/check_clipboard_icon.png', alt: 'Copy Complete Icon' });
var copyIcon = Object.assign(document.createElement('img'), { src: './images/copy_clipboard_icon.png', alt: 'Copy Icon' });
// 복사 버튼 내용 및 클래스 업데이트
button.innerHTML = '';
button.appendChild(successIcon);
button.setAttribute('class', 'copy-button copy-message');
// 1.5초 후에 버튼을 초기 상태로 되돌림
setTimeout(function() {
button.setAttribute('class', 'copy-button');
button.innerHTML = '';
button.appendChild(copyIcon);
}, 1500);
});
});
</script>
- CSS
/* 전체 코드 블록 설정 */
pre {
position: relative; /* 상대 위치 설정 */
overflow: visible; /* 내용이 넘칠 경우 가시성 설정 */
}
/* 복사 버튼 스타일 */
pre .copy-button {
opacity: 0; /* 초기에는 투명도 0으로 설정 */
position: absolute; /* 절대 위치 설정 */
right: 8px;
top: 8px;
padding: 4px;
background: #2c2d31; /* 배경색 설정 */
border-radius: 5px; /* 테두리 모서리 둥글게 설정 */
border-color: #9ca3af; /* 테두리 색상 설정 */
border-width: 1px; /* 테두리 두께 설정 */
transition: opacity .3s ease-in-out; /* 투명도 전환 효과 설정 */
}
/* 복사 버튼 아이콘 스타일 */
pre .copy-button img {
width: 24px;
height: 24px;
vertical-align: middle;
}
/* 마우스 호버 시 복사 버튼 나타나는 효과 */
pre:hover .copy-button {
opacity: 1; /* 마우스 호버 시 투명도 1로 설정 */
}
/* 복사 버튼 호버 시 효과 */
pre .copy-button:hover {
color: #eee; /* 텍스트 색상 변경 */
transition: all ease-in-out 0.3s; /* 모든 속성에 호버 시 효과 적용 */
}
/* 복사 버튼 클릭 시 효과 */
pre .copy-button:active {
border-width: 3px; /* 클릭 시 테두리 두께 변경 */
border-color: #FFA500; /* 클릭 시 테두리 색상 변경 */
transition: all ease-out 0.1s; /* 모든 속성에 클릭 시 효과 적용 */
}
/* 복사 성공 메시지 스타일 */
.copy-message:before {
font-family: SUIT, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
content: "Copied";
position: absolute; /* 절대 위치 설정 */
font-weight: bold;
font-size: 14px;
left: -10px;
bottom: 49px;
padding: 2px;
color: #eee; /* 텍스트 색상 설정 */
background: #2c2d31; /* 배경색 설정 */
border-radius: 5px; /* 테두리 모서리 둥글게 설정 */
}
/* 복사 성공 메시지 테두리 스타일 (말풍선 모양)*/
.copy-message:after {
border-top: 8px solid #2c2d31;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 0px solid transparent;
content: "";
position: absolute; /* 절대 위치 설정 */
bottom: 41px; /* 아래쪽 여백 */
}
이 코드는 현재 사용하고 있는 hELLO 스킨에 맞게 작성해본 코드이다. 사용자에 따라 CSS를 더 예쁘게 꾸미거나, 이미지 버튼이 아닌 글자 버튼으로 만들어 사용하는 등 알맞은 스타일로 꾸며서 사용하는 것을 추천한다.
'티스토리' 카테고리의 다른 글
[티스토리] 수학 수식 입력하기 (KaTeX) (0) | 2023.12.16 |
---|