如何用JavaScript实现圣经经文高亮?解决误插入<mark>标签问题
圣经经文高亮功能修复
问题现状
已实现两种高亮功能:双击经文整节高亮、鼠标选中部分内容高亮,但存在单击经文空白处会插入空<mark>标签的问题。需要满足以下条件才执行部分内容高亮:
- 用户选中了非空白的有效文本
- 当前经文未添加
highlight类(整节高亮标记)
修复后的代码
JavaScript 代码
$('.bogus').on('dblclick', function() { const { book, chapter, verse } = $(this).data(); highlighter(book, chapter, verse); }); function highlighter(book, chapter, verse) { const verseEl = $("#" + verse); // 切换整节高亮状态并同步到后端 if (verseEl.hasClass('highlight')) { verseEl.removeClass('highlight'); $.ajax({ type: "POST", url: "{{ base_url }}bible/removeHighlight/", data: { book, chapter, verse }, dataType: "json", encode: true, }); } else { verseEl.addClass('highlight'); $.ajax({ type: "POST", url: "{{ base_url }}bible/addHighlight/", data: { book, chapter, verse }, dataType: "json", encode: true, }); } } // 给选中内容添加<mark>标签 function markSelection() { const selection = window.getSelection(); // 确保有有效选区 if (!selection.rangeCount) return; const range = selection.getRangeAt(0); // 排除选区折叠(未选中任何内容)的情况 if (range.collapsed) return; const selectedContent = range.extractContents(); const mark = document.createElement("mark"); mark.appendChild(selectedContent); range.insertNode(mark); // 清除选区,避免重复触发 selection.removeAllRanges(); } // 获取选中的文本内容(自动去除首尾空白) function getSelectionText() { let text = ""; if (window.getSelection) { text = window.getSelection().toString().trim(); } else if (document.selection && document.selection.type != "Control") { text = document.selection.createRange().text.trim(); } return text; } $('.bogus').on("mouseup", function(e) { const { verse } = $(this).data(); const verseEl = $("#" + verse); // 整节已高亮则直接跳过 if (verseEl.hasClass("highlight")) return; const selectedText = getSelectionText(); // 仅当选中非空文本时执行高亮 if (selectedText) { markSelection(); } })
HTML 代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <span id="1" class="bogus" data-book="Genesis" data-chapter="1" data-verse="1"> <sup class="verse">1</sup> <span id="verseText-1">In the beginning God created the heaven and the earth</span> </span>
核心修改点
getSelectionText优化:添加trim()自动去除选中内容的首尾空白,避免仅选中空格时触发高亮markSelection安全校验:增加选区存在性和非折叠判断,确保只有选中有效内容时才创建<mark>标签;操作后清除选区防止重复触发- 事件逻辑简化:使用提前返回减少代码嵌套,提升可读性和维护性
内容的提问来源于stack exchange,提问作者Andrew Rout
相关产品推荐
相关产品推荐

