본문 바로가기
✍️ 기록/Javascript

[highlight.js] 구문 강조, 번호 추가, navigator.clipboard 복사

by 김물사 2025. 5. 7.

📌 highlight.js란? 

- highlight.js는 코드 구문 강조를 쉽게 구현할 수 있도록 도와주는 JavaScript 라이브러리

- 코드 블록을 감지해서 언어에 맞게 색상과 스타일을 자동으로 적용

- 다양한 테마를 활용하여 디자인에 맞게 코드 스타일 적용 가능

 

🔗 highlight.js.org

 

highlight.js

Usage highlight.js can be used in different ways such using CDNs, hosting the bundle yourself, as a Vue plug-in, as ES6 modules, with Node.js, and web workers. See our README on GitHub for more details. As a Module Highlight.js can be used with Node on the

highlightjs.org

 

 

📍 다운로드 및 CDN

✅ 다운로드 후 사용

https://highlightjs.org/download

🗂️ 원하는 언어를 선택하여 다운로드를 할 수 있습니다.

 

✅ CDN 

// cdn
// CSS 테마 선택 가능
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
// JS
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>

 

📍 사용 방법

<div>
  <pre>
    <code class="language-javascript">
      function test() {
        console.log('test');
      }
    </code>
  </pre>
</div>
<script>
  document.addEventListener('DOMContentLoaded', () => {
    hljs.highlightAll();
  });
</script>

✅ highlight.js 사용 완료

 

🔽 테마 변경하기 

🔗 Demo 

데모에서 언어와 테마도 미리 확인하여 원하는 테마를 확인 후 적용!

 

//✅ default -> atom-one-dark 변경
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">

 

✅ EX) atom-one-dark 테마를 사용하기 위해 기존 default 연결을 atom-one-dark로 변경하면 끝!

 

📍 언어 설정

code 태그에 사용 언어 클래스를 입력하면 원하는 언어에 맞게 적용할 수 있습니다.

- javascript, css 적용 

 

📍 라인 번호 추가

<!-- Line Numbers -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js"></script>

<script>
  document.addEventListener('DOMContentLoaded', () => {
    hljs.highlightAll();

    // 라인 넘버 적용
    hljs.initLineNumbersOnLoad();
  });
</script>

 

 

✅ initLineNumbersOnLoad 사용 없이 \n 줄바꿈 기준으로 line number 추가하기

// highlight 적용
hljs.highlightAll();
// line numbers 추가
document.querySelectorAll('pre code').forEach(code => {
  const lines = code.innerText.split('\n');
  const lineNumbers = document.createElement('div');
  lineNumbers.className = 'line-numbers';
  lines.forEach((_, i) => {
    const span = document.createElement('span');
    span.textContent = i + 1;
    lineNumbers.appendChild(span);
  });
  const codeBox = code.closest('.code-box');
  const preEl = code.parentElement;
  if (codeBox && preEl) {
    codeBox.insertBefore(lineNumbers, preEl);
  }
});

✅ hljs 전체 감싸고 있는 .code-box 자식으로 pre 태그 앞에 추가!

스타일도 code와 비슷하게 맞춰주면 끝!

 

📍 복사, 적용 언어 표시 추가

✅
.code-box{
    position:relative;
  }
  .code-head{
    position:absolute;
    top:5px;
    right:0;
  }
  .label, .copy-btn {
    padding: 4px 10px;
    border:1px solid #dbdbdb;
    background: #000;
    font-size:14px;
    color: #fff;
  }
  .copy-btn {
    cursor: pointer;
  }
 
✅ 
<div class="code-box">
  <div class="code-head">
    <span class="label">JavaScript</span>
    <button class="copy-btn">복사</button>
  </div>
  <pre>
    <code class="language-javascript">
      // language-javascript
      function test() {
        console.log('test');
      }
    </code>
  </pre>
</div>
<div class="code-box">
  <div class="code-head">
    <span class="label">CSS</span>
    <button class="copy-btn">복사</button>
  </div>
  <pre>
    <code class="language-css">
      /* language-css */
      .test{
        position: relative;
        border:1px solid red;
      }
    </code>
  </pre>
</div>

✅
<script>
  document.addEventListener('DOMContentLoaded', () => {
    // highlight 적용
    hljs.highlightAll();
    // 라인 넘버 적용
    hljs.initLineNumbersOnLoad();

    // 복사
    const copyBtns = document.querySelectorAll('.copy-btn');
    copyBtns.forEach(item => {
      item.addEventListener('click', () => {
        const codeElement = item.closest('.code-box').querySelector('code');
        const codeText = codeElement.innerText;
        if (navigator.clipboard) {
          navigator.clipboard.writeText(codeText)
            .then(() => {
              item.textContent = '복사 완료';
              setTimeout(() => {
                item.textContent = '복사';
              }, 1500);
            })
            .catch(err => {
              item.textContent = '실패';
            });
        }
      });
    });
  });
</script>

 

✅ 복사 확인 완료!!

innerText를 통해 <code>내 공백, 주석 화면에 보이는 내용 그대로 복사 되기에 기능 추가 시 참고

 

 

✍️ 기록

 

감사합니다. 😁

반응형
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.