clipboard API

woolee의 기록보관소·2022년 11월 11일
0

FE 기능구현 연습

목록 보기
22/33

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer"/>
  <title>clipboard</title>
</head>
<body>
  
  <div class="container">
    <div class="label">
      복사 영역
    </div>
    <div class="copy-text">
      <input class="text" type="text">
      <button>
        <i class="fa fa fa-clone"></i>
      </button>
    </div>
  </div>

  <script src="app.js"></script>
</body>
</html>

CSS

.container
컨테이너 가운데로 정렬

.copy-text
input이랑 button을 가로 정렬하기 위해 display:flex;

.copy--text button:before/after
말풍선을 before/after로 만든 후에 display:none;으로 지워두고
active 클래스가 붙으면 display:block;으로 보여주기

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background: #f0f2f7;
}

.container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.label {
  padding: 10px;
  font-size: 18px;
  color: #111;
}

.copy-text {
  position: relative;
  padding: 10px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 10px;
  display: flex;
}

.copy-text input.text {
  padding: 10px;
  font-size: 18px;
  color: #555;
  border: none;
  outline: none;
}

.copy-text button {
  padding: 10px;
  background: #5784f5;
  color: #fff;
  font-size: 18px;
  border: none;
  outline: none;
  border-radius: 10px;
  cursor: pointer;
}

.copy-text button:active {
  background: #809ce2;
}

.copy-text button:before {
  content: "Copied";
  position: absolute;
  top: -50px;
  right: 0px;
  background: #5c81dc;
  padding: 8px 10px;
  border-radius: 20px;
  font-size: 15px;
  display: none;
}

.copy-text button:after {
  content: "";
  position: absolute;
  top: -22px;
  right: 25px;
  width: 10px;
  height: 10px;
  background: #5c81dc;
  transform: rotate(45deg);
  display: none;
}

/* 
active 붙기 전에는 display:none 해두었다가 
active 붙으면 display:block으로 보여주기 */
.copy-text.active button:before,
.copy-text.active button:after {
  display: block;
}

JS

input.select();
document.execCommend('copy');

HTMLInputElement.select()는 input 또는 textarea의 모든 텍스트를 선택하는 메서드. 복사할 문자가 input/textarea처럼 selection 가능한 입력 영역이면서 hidden이 아니어야 한다.
document.execCommend('copy'); 복사하기
document.execCommend('cut'); 자르기
document.execCommend('paste'); 붙여넣기

는 권장되지 않으므로

-->>

clipboard API를 사용했다.

navigator.clipboard.writeText()로 값을 받아와서(복사 기능)
navigator.clipboard.readText()로 뿌려주는 건데(붙여넣기 기능),

그냥 작성하면 값이 안 받아와지는 걸 보니 비동기로 동작하는 것 같아서(web api니까!) async/await을 사용해줬다. 이유가 맞는지는 모르겠다.
여기서 예외 처리는 할 필요 없으므로 try-catch는 안 해줬다.

아래 코드처럼 단순히 alert로 처리하지 않고 요소에 꽂아넣는 식으로 개발하면 응용할 수 있겠다.

let copyText = document.querySelector('.copy-text');

copyText.querySelector('button').addEventListener('click', async function () {
  let input = copyText.querySelector('input.text');

  // navigator.clipboard.writeText()로 값을 받아와서 readText()로 뿌려주는 방법 
  await navigator.clipboard.writeText(input.value);
  copyText.classList.add('active');

  setTimeout(async function () {
    // await 처리 안하면 text에 값이 안 담기네..
    const text = await navigator.clipboard.readText();
    alert(`${text}가 복사되었어요.`);
    copyText.classList.remove('active');
  }, 2500);
})

참고

Copy to Clipboard using HTML, CSS & JavaScript

JavaScript 클립보드 복사하는 방법(Clipboard API, clipboard.js)

profile
https://medium.com/@wooleejaan

0개의 댓글