본문 바로가기

웹 개발 알아두기/티스토리

코드 클립보드에 복사하기

반응형

기술블로그인 만큼 코드가 많이 들어가는 데 일일이 복사하는 불편함을 덜고자 클립보드 복사기능을 추가하기로 하였습니다.

완성코드

<script>
  setTimeout(() => {
    const copyPreEls = document.querySelectorAll("pre")
    let messageShowing = false
    copyPreEls.forEach(el => {
      el.addEventListener('mouseenter', () => {
        if (!messageShowing) {
          const messageEl = document.createElement('p')
          messageEl.innerText = '더블클릭으로 복사'
          messageEl.style.position = 'absolute'
          messageEl.style.top = '15px'
          messageEl.style.right = '5px'
          messageEl.style.backgroundColor = '#f7ee4b'
          messageEl.style.padding = '5px 10px'
          messageEl.style.borderRadius = '5px'
          messageEl.style.transform = 'scale(0)'
          messageEl.style.transition = '.4s ease'
          setTimeout(() => {
            messageEl.style.transform = 'scale(1)'
          }, 10)

          setTimeout(() => {
            messageEl.style.transform = 'scale(0)'
          }, 1600)

          el.appendChild(messageEl)
          messageShowing = true

          setTimeout(() => {
            el.removeChild(messageEl)
            messageShowing = false
          }, 1800)
        }
      })

      el.addEventListener('dblclick', () => {
        // Copy the text inside the text field   
        navigator.clipboard.writeText(el.querySelector('code.hljs').textContent);  

        // Alert the copied text                
        const resultMessageEl = document.createElement('div')
        resultMessageEl.innerText = 'Copied'
        resultMessageEl.style.position = 'fixed'
        resultMessageEl.style.top = '15px'
        resultMessageEl.style.right = '15px'
        resultMessageEl.style.backgroundColor = '#f7ee4b'
        resultMessageEl.style.padding = '5px 10px'
        resultMessageEl.style.borderRadius = '5px'
        resultMessageEl.style.transform = 'scale(0)'
        resultMessageEl.style.transition = '.4s ease'
        setTimeout(() => {
          resultMessageEl.style.transform = 'scale(1)'
        }, 10)

        setTimeout(() => {
          resultMessageEl.style.transform = 'scale(0)'
        }, 1600)

        document.body.appendChild(resultMessageEl)

        setTimeout(() => {
          document.body.removeChild(resultMessageEl)
        }, 2000)
      })
    });
  }, 100)
</script>

구현하기

클립보드로 복사하는 기능은 추가설정이 필요 없고 구현이 가장 수월하다고 판단하여 자바스크립트에서 제공하는 내비게이터 객체를 사용하기로 하였습니다. 작동은 아래처럼 내비게이터 객체의 클립보드를 호출하고 원하는 텍스트를 저장하는 방법입니다.

navigator.clipboard.writeText(copyText.value);

다음으로, 코드를 복사하기 위해 코드요소에 이벤트를 연결해야 하는데요. 코드요소와 코드 클래스를 통해 전체요소를 잡고 루프를 통해 구현하는 방식으로 결정하였습니다.

이벤트는 아이템을 개별복사하는 경우도 있으므로 클릭이 아닌 더블클릭 이벤트로 연결하고

const copyPreEls = document.querySelectorAll("pre")

copyPreEls.forEach(el => {
  el.addEventListener('dblclick', () => {
    // Copy the text inside the text field
    navigator.clipboard.writeText(el.textContent);

    // Alert the copied text
    alert("Copied to Clipboard");
  })
})

클립복사가 가능하다는 것을 유저에게 알리기 위해 메시지 박스를 스타일과 함께 추가합니다. 이때, 메시지 박스는 타이머를 사용하여 자동으로 사라지도록 구현하면 코드는 완성인데요.

const copyPreEls = document.querySelectorAll("pre")

copyPreEls.forEach(el => {
  el.addEventListener('mouseenter', () => {
    const messageEl = document.createElement('p')
    messageEl.innerText = '더블클릭으로 복사'      
    messageEl.style.position = 'absolute'
    messageEl.style.top = '5px'
    messageEl.style.right = '5px'
    messageEl.style.color = 'absolute'
    messageEl.style.backgroundColor = '#f7ee4b'
    messageEl.style.padding = '5px 10px'
    messageEl.style.borderRadius = '5px'
    messageEl.style.transform = 'scale(0)'
    messageEl.style.transition = '.4s ease'
    setTimeout(() => {
      messageEl.style.transform = 'scale(1)'
    }, 10)

    setTimeout(() => {
      messageEl.style.transform = 'scale(0)'
    }, 1600)

    el.appendChild(messageEl)
    setTimeout(() => {
      el.removeChild(messageEl)
    }, 2000)
  })

  el.addEventListener('dblclick', () => {      
    setTimeout(() => {
      // Copy the text inside the text field   
      navigator.clipboard.writeText(el.querySelector('code.hljs').textContent);
    }, 2200)         

    // Alert the copied text
    alert("클립보드에 복사되었습니다");
  })
});

관리자 페이지에 보면 좌측에 '스킨편집'이라는 기능이 있는데요. 해당 메뉴를 선택하면 스킨편집 페이지로 이동합니다.

열린 화면에서 'html 편집'이라는 버튼을 누르고

CSS파일을 엽니다. pre요소를 찾아 아래 스타일을 추가합니다. 해당 스타일은 알림 메시지가 코드 박스 안에서 표시되도록 해 줍니다

position: relative;

다음으로 'HTML' 파일로 이동하여 아래 코드를 복사하여 (타이머는 요소가 준비되었을 때 코드가 작동하도록 합니다. 또 알림 메시지가 중복을 생성되는 것을 방지하기 위해 조건을 추가하였습니다)

<script>
  setTimeout(() => {
    const copyPreEls = document.querySelectorAll("pre")
    let messageShowing = false
    copyPreEls.forEach(el => {
      el.addEventListener('mouseenter', () => {
        if (!messageShowing) {
          const messageEl = document.createElement('p')
          messageEl.innerText = '더블클릭으로 복사'
          messageEl.style.position = 'absolute'
          messageEl.style.top = '15px'
          messageEl.style.right = '5px'
          messageEl.style.backgroundColor = '#f7ee4b'
          messageEl.style.padding = '5px 10px'
          messageEl.style.borderRadius = '5px'
          messageEl.style.transform = 'scale(0)'
          messageEl.style.transition = '.4s ease'
          setTimeout(() => {
            messageEl.style.transform = 'scale(1)'
          }, 10)

          setTimeout(() => {
            messageEl.style.transform = 'scale(0)'
          }, 1600)

          el.appendChild(messageEl)
          messageShowing = true

          setTimeout(() => {
            el.removeChild(messageEl)
            messageShowing = false
          }, 1800)
        }
      })

      el.addEventListener('dblclick', () => {
        // Copy the text inside the text field   
        navigator.clipboard.writeText(el.querySelector('code.hljs').textContent);  

        // Alert the copied text                
        const resultMessageEl = document.createElement('div')
        resultMessageEl.innerText = 'Copied'
        resultMessageEl.style.position = 'fixed'
        resultMessageEl.style.top = '15px'
        resultMessageEl.style.right = '15px'
        resultMessageEl.style.backgroundColor = '#f7ee4b'
        resultMessageEl.style.padding = '5px 10px'
        resultMessageEl.style.borderRadius = '5px'
        resultMessageEl.style.transform = 'scale(0)'
        resultMessageEl.style.transition = '.4s ease'
        setTimeout(() => {
          resultMessageEl.style.transform = 'scale(1)'
        }, 10)

        setTimeout(() => {
          resultMessageEl.style.transform = 'scale(0)'
        }, 1600)

        document.body.appendChild(resultMessageEl)

        setTimeout(() => {
          document.body.removeChild(resultMessageEl)
        }, 2000)
      })
    });
  }, 100)
</script>

최대한 아래쪽에 붙여 넣습니다.

완성된 화면

코드를 넣고 저장하면 아래와 같이 클립보드를 사용합니다.

이상으로 티스토리에 클립보드기능을 추가하는 방법을 보았습니다.


참고

How To Copy to Clipboard (w3schools.com)

 

How To Copy to Clipboard

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

 

728x90
반응형