如何在HTML内容编辑时调用JS函数实现highlight.js实时语法高亮?
实现contenteditable代码块的实时语法高亮(基于highlight.js)
要让可编辑的<code>块实现实时语法高亮,你可以通过监听编辑事件,在内容变化时重新执行高亮逻辑,同时解决光标错位问题,具体实现如下:
步骤1:修改HTML结构
给可编辑的<code>元素添加唯一ID,方便后续JS精准获取目标元素:
<link rel="stylesheet" href="{% static 'tokyo-night-dark.min.css' %}"> <div class="main"> <pre><code id="editable-code" contenteditable>{{code}}</code></pre> </div>
步骤2:编写实时高亮的JS逻辑
直接调用hljs.highlightAll()会影响页面所有代码块,还会导致可编辑区域光标错位,建议针对单个元素处理,并在高亮前后保存、恢复光标位置:
<script> // 获取目标代码块元素 const codeBlock = document.getElementById('editable-code'); // 保存当前光标位置 function saveCursorPosition() { const selection = window.getSelection(); if (selection.rangeCount === 0) return null; const range = selection.getRangeAt(0); const preRange = range.cloneRange(); preRange.selectNodeContents(codeBlock); preRange.setEnd(range.startContainer, range.startOffset); return preRange.toString().length; } // 恢复光标到指定位置 function restoreCursorPosition(pos) { const selection = window.getSelection(); const range = document.createRange(); range.setStart(codeBlock.firstChild, pos); range.collapse(true); selection.removeAllRanges(); selection.addRange(range); } // 执行单个代码块的高亮 function highlightCode() { const cursorPos = saveCursorPosition(); // 可手动指定语言(比如'python'),不填则自动检测语法 hljs.highlightElement(codeBlock); restoreCursorPosition(cursorPos); } // 监听编辑事件,内容变化时触发高亮 codeBlock.addEventListener('input', highlightCode); // 页面加载时初始化高亮 window.addEventListener('load', highlightCode); </script>
关键说明
- 用
input事件监听编辑:contenteditable元素的输入、删除、粘贴等操作都会触发该事件,覆盖所有编辑场景。 - 单个元素高亮更高效:
hljs.highlightElement()只处理目标代码块,避免影响页面其他代码块,性能更优。 - 光标位置修复:高亮会重新渲染代码块DOM结构,通过保存和恢复光标位置解决错位问题。
- 初始化高亮:页面加载完成后执行一次高亮,确保初始内容也有语法高亮效果。
内容的提问来源于stack exchange,提问作者Craze XD
相关产品推荐
相关产品推荐

