我知道这段代码有效,而且它现在已经停止工作了。我正在研究一个人的荧光笔工具,但如果我输入一个单词然后输入mark
,它会突出显示实际的标记元素。这是我的代码:
function Search (tagC) {
var notes = document.getElementsByClassName("NoteOp");
for (var i = 0; i < notes.length; i++) {
var n = notes[i];
var tagOut = tagC
var tagFront = tagOut.slice(0, -9);
var tagLast = tagOut.slice(-9);
n.innerHTML = n.innerHTML.replace(new RegExp("\\b(" + tagFront + ")\\b", "gim"), "<mark class=" + tagLast + ">$1</mark>");
if(window.Bold === "Yes") {
$("mark").css("font-weight", "bold");
}
}
}
tagFront
是搜索词,而tagLast
是一个总是有9个字母的类。在编码中看到的任何问题?
tagC
的一个例子是:
testYelColBox
...我正在搜索的文字如下:
<div id="NoteHolder">
<p class="NoteOp">This is a test paragraph uses to TeSt filters.</p>
<p class="NoteOp">Random words, I need to see if it will mess up mark</p>
</div>
主要问题:即使我的代码有\b
元字符选择器,为什么我的代码会标记HTML元素?
答案 0 :(得分:1)
你的问题似乎是这样的:
如果您首先突出显示一个单词,它就能正常工作。但是现在你的HTML有<mark>
个标签,所以如果现在你第二次用搜索词&#34;标记&#34; 进行搜索,那么这个标签会得到一个嵌套标记,这是不希望的,使您的HTML无效。
\b
转义匹配搜索字符串中字符序列从字母数字字符切换到非字母数字字符的任何位置,反之亦然。这意味着\b
也会与<
<mark ...>
之后的位置匹配,并且位于k
之后的位置(由于后面的空格)。
通过仅将其应用于文本节点而不是HTML元素来进行受控替换。为此,您需要遍历节点,检查其类型,以及何时它们是文本节点,执行替换。由于替换涉及插入HTML元素,您实际上应该将该文本节点拆分为之前的内容,标记元素以及之后的内容。
这是执行所有这些操作的代码:
function clear() {
var notes = document.getElementsByClassName("NoteOp");
for (var i = 0; i < notes.length; i++) {
var n = notes[i];
// Remove all opening/closing mark tags
n.innerHTML = n.innerHTML.replace(/<\/?mark.*?>/gm, "");
}
}
function highlight(tagC) {
// Sanity check
if (tagC.length <= 9) return; // ignore wrong input
var notes = document.getElementsByClassName("NoteOp");
// Split into parts before entering loop:
var tagFront = tagC.slice(0, -9);
var tagLast = tagC.slice(-9);
// Escape tagFront characters that could conflict with regex syntax:
tagLast = tagLast.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
var regex = new RegExp("\\b(" + tagFront + ")\\b", "gim");
// Create a template of the highlight that can be cloned
var mark = document.createElement('mark');
mark.setAttribute('class', tagLast);
// Loop over notes
for (var i = 0; i < notes.length; i++) {
// Create a span that will have the contents after replacements
var span = document.createElement('span');
// Go through all child nodes of this note
var nodes = notes[i].childNodes;
for (var j = 0; j < nodes.length; j++) {
var node = nodes[j];
if (node.nodeType === 3) {
// Only if text node, perform replacement
parts = node.textContent.split(regex);
// As regex has capture group, also the split expression is a part
for (var k = 0; k < parts.length; k++) {
// Add this part
if (k % 2) {
// Add highlighted text
mark.textContent = parts[k];
span.appendChild(mark.cloneNode(true));
} else {
// Add text part that did not match as such
span.appendChild(document.createTextNode(parts[k]));
}
}
} else {
// Non-text nodes are just copied as they are
span.appendChild(node.cloneNode(true));
}
}
// Replace note contents with new contents
notes[i].innerHTML = span.innerHTML;
}
// Setting style for CSS class should happen outside of the loop
$("mark").css("font-weight", window.Bold === "Yes" ? "bold": "normal");
}
// I/O
var inp = document.querySelector('#inp');
var btnMark = document.querySelector('#mark');
var btnClear = document.querySelector('#clear');
btnMark.onclick = function () {
highlight(inp.value + 'YelColBox');
}
btnClear.onclick = clear;
&#13;
Type text to be highlighted and press Mark:<br>
<input id="inp" value="">
<button id="mark">Mark</button>
<button id="clear">Clear</button>
<div id="NoteHolder">
<p class="NoteOp">This is a test paragraph uses to TeSt filters.</p>
<p class="NoteOp">Random words, I need to see if it will mess up mark</p>
</div>
&#13;