🎉

Vanilla JS で生成した DOM に highlight.js を適用

2024/03/23に公開

はじめに

marked.js でマークダウンを実装し、さらに highlight.js でシンタックスハイライトを実装した。highlight.js の導入で躓いたため記録しておく。

概要

<pre><code> 入りの DOM を生成
 ↓
highlight.js の適用は DOM 生成後に行う必要がありそう
 ↓
addEventListener でタイミング調整 (NG)
(※ ページ更新時に遅れて発火するイベントがなさそう)
 ↓
read() 関数の呼出直後に記述 (NG)
 ↓
read() 関数の中の最後に記述 (OK)

ソースコード

diary.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta http-equiv="content-security-policy" content="script-src 'self' *.cloudflare.com *.cloudflareinsights.com">
    <title>diary</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/base16/default-dark.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
    <script src="inc/diary.js"></script>
</head>
<body>
    <header></header>
    <main id="diary"></main>
    <footer></footer>
</body>
</html>
inc/diary.js
async function read() {

    const diary = document.getElementById('diary');
    const df = document.createDocumentFragment();
    const doc = document.createElement('div');

    doc.innerHTML = marked.parse('ここにマークダウン記法の文章');

    df.appendChild(doc);
    diary.appendChild(df);

    hljs.highlightAll(); // ← ここに記載するとOK

}

// =============================================================
// == main =====================================================

document.addEventListener('DOMContentLoaded', function() {

    read();
    // hljs.highlightAll(); // ← ここに記載するとNG

});

// =============================================================

上記の通り、read(); の直後に hljs.highlightAll(); を記述すると動かないが、read() 関数の中の最後に記述すると、シンタックスハイライトが行われる。

一言

なんでこんなことが起こるかわからん!と思っていたけれど、もしかして async 関数だからかな?

参考サイト

Discussion