innerHtml中的Javascript搜索排除html标记
Javascript search in innerHtml Exclude html tags
我用javascript编写了一个自定义搜索,用于突出显示文本。
场景是获取CCD_ 1并搜索文本并突出显示它们。
问题:如果用户搜索i,则会发现<div>
标签中的i,并且一切都一团糟。
var textBlock=document.body.innerHTML;
searchIndex = textBlock.toLowerCase().indexOf(what.toLowerCase(), 0);
while(searchIndex >= 0)
{
++counter;
ID = "result" + counter;
replacement = '<span id='+ID+' style="background-color:#f0da1e">'+what+'</span>';
textBlock = textBlock.substring(0, searchIndex) + replacement + textBlock.substring(searchIndex + what.length, textBlock.length);
searchIndex = textBlock.toLowerCase().indexOf(what.toLowerCase(), (searchIndex + replacement.length));
}
document.body.innerHTML=textBlock;
如何跳过标签中的已建立索引?
像这样的东西:
if(isTag(searchIndex))
//do nothing
更新:
如果我使用innerText
而不是innerHtml
,那么我所有的文本格式和样式都将被破坏。
var textBlock=document.body.innerText;
document.body.innerHTML=textBlock;
一种可能的解决方案是使用节点:
- 获取
body
子节点(而不是innerHTML
( - 遍历节点:
- 如果是文本节点(叶子(:搜索要替换的字符串
- 如果它是一个元素节点:获取并遍历子节点
下面是一个示例函数,它将突出显示您指定的文本:
function highlightText(nodeList, what) {
// traverse all the children nodes
for (var x = 0; x < nodeList.length; x++) {
// text node, search directly
if (nodeList[x].nodeType == 3) {
// if it contains the text that you are looking for, proceed with the replacement
if (nodeList[x].textContent.indexOf(what) >= 0) {
// your code (mostly :P)
var ID = "result" + counter;
var replacement = '<span id="'+ID+'" style="background-color:#f0da1e">'+what+'</span>';
var textBlock = nodeList[x].textContent;
var searchIndex = nodeList[x].textContent.indexOf(what);
while(searchIndex >= 0)
{
++counter;
ID = "result" + counter;
replacement = '<span id="'+ID+'" style="background-color:#f0da1e">'+what+'</span>';
textBlock = textBlock.substring(0, searchIndex) + replacement + textBlock.substring(searchIndex + what.length, textBlock.length);
searchIndex = textBlock.toLowerCase().indexOf(what.toLowerCase(), (searchIndex + replacement.length));
}
// create a new element with the replacement text
var replacementNode = document.createElement("span");
replacementNode.innerHTML = textBlock;
// replace the old node with the new one
var parentN = nodeList[x].parentNode;
parentN.replaceChild(replacementNode, parentN.childNodes[x]);
}
} else {
// element node --> search in its children nodes
highlightText(nodeList[x].childNodes, what);
}
}
}
这里有一个示例演示(也可以在这个JSFiddle上获得(:
var counter = 0;
function highlightText(nodeList, what) {
// traverse all the children nodes
for (var x = 0; x < nodeList.length; x++) {
// text node, search directly
if (nodeList[x].nodeType == 3) {
// if it contains the text that you are looking for, proceed with the replacement
if (nodeList[x].textContent.indexOf(what) >= 0) {
// your code (mostly :P)
var ID = "result" + counter;
var replacement = '<span id="'+ID+'" style="background-color:#f0da1e">'+what+'</span>';
var textBlock = nodeList[x].textContent;
var searchIndex = nodeList[x].textContent.indexOf(what);
while(searchIndex >= 0)
{
++counter;
ID = "result" + counter;
replacement = '<span id="'+ID+'" style="background-color:#f0da1e">'+what+'</span>';
textBlock = textBlock.substring(0, searchIndex) + replacement + textBlock.substring(searchIndex + what.length, textBlock.length);
searchIndex = textBlock.toLowerCase().indexOf(what.toLowerCase(), (searchIndex + replacement.length));
}
// create a new element with the replacement text
var replacementNode = document.createElement("span");
replacementNode.innerHTML = textBlock;
// replace the old node with the new one
var parentN = nodeList[x].parentNode;
parentN.replaceChild(replacementNode, parentN.childNodes[x]);
}
} else {
// element node --> search in its children nodes
highlightText(nodeList[x].childNodes, what);
}
}
}
var nodes = document.body.childNodes;
console.log(nodes);
highlightText(nodes, "ar");
<p>Men at some time are masters of their fates: The fault, dear Brutus, is not in our stars, but in ourselves, that we are underlings.</p>
<p><b>William Shakespeare</b>, <em>Julius Caesar</em> (Act I, Scene II)</p>
这个解决方案的一个问题是,它添加了额外的span
元素来包装包含搜索字符串的每个文本节点(尽管我不知道这会给您带来多大的不便(。它也是递归的,您可能想研究一个迭代的替代方案。
更新我知道你没有要求这样做,但我认为这可能很有趣:通过重新排序参数列表,并在第一次调用时添加一些初始化,你可以让用户的函数更干净,同时添加一些有趣的功能:
function highlightText(what, node) {
// initialize values if first call
node = node || document.body;
var nodeList = node.childNodes;
// traverse all the children nodes
for (var x = 0; x < nodeList.length; x++) {
// text node, search directly
if (nodeList[x].nodeType == 3) {
// if it contains the text that you are looking for, proceed with the replacement
if (nodeList[x].textContent.indexOf(what) >= 0) {
// your code (mostly :P)
var ID = "result" + counter;
var replacement = '<span id="'+ID+'" style="background-color:#f0da1e">'+what+'</span>';
var textBlock = nodeList[x].textContent;
var searchIndex = nodeList[x].textContent.indexOf(what);
while(searchIndex >= 0)
{
++counter;
ID = "result" + counter;
replacement = '<span id="'+ID+'" style="background-color:#f0da1e">'+what+'</span>';
textBlock = textBlock.substring(0, searchIndex) + replacement + textBlock.substring(searchIndex + what.length, textBlock.length);
searchIndex = textBlock.toLowerCase().indexOf(what.toLowerCase(), (searchIndex + replacement.length));
}
// create a new element with the replacement text
var replacementNode = document.createElement("span");
replacementNode.innerHTML = textBlock;
// replace the old node with the new one
var parentN = nodeList[x].parentNode;
parentN.replaceChild(replacementNode, parentN.childNodes[x]);
}
} else {
// element node --> search in its children nodes
highlightText(what, nodeList[x]);
}
}
}
现在,要在页面中搜索字符串,您只需执行以下操作:
highlightText("ar");
(不需要像以前那样的第二个参数(
但是,如果您将一个元素作为第二个参数传递给函数,那么搜索将只在指定的元素中执行,而不是在整个页面中执行:
highlightText("ar", document.getElementById("highlight_only_this"));
您可以在这个JSFiddle上看到一个演示:http://jsfiddle.net/tkm5696w/2/
也许您可以使用innerText
而不是innerHTML
。您可以使用innerHtml
0。
innerText
和textContent
之间的差异可以在以下链接中。
MDN-text内容
Internet Explorer推出了element.innerText
。意图相似,但有以下区别:
- 而textContent获取所有元素的内容,包括和元素,IE特定属性innerText没有
- innerText知道样式,不会返回隐藏的文本元素,而textContent会
- 由于innerText知道CSS样式,它将触发回流,而textContent不会
innerHtml将搜索给定元素内的文本和元素。使用innerText或textContent只搜索文本(我知道这就是你想要的(
- 制作一个不带HTML a标记但在动画播放完毕后指向其他页面的超链接
- HTML标记在脚本标记中工作
- 是否可以添加这行“;“照原样”;在HTML标记中
- 一个正则表达式,用于从JS中的HTML标记中删除id、样式和类属性
- 如果匹配项在特定的html标记中,则跳过regex匹配
- 使用 Pure JS 更改 HTML 标记名称
- 如何使用javascript选择字符串的部分,添加html标记或删除部分
- HTML标记,包含带引号的JavaScript代码中的引号
- 如何在JavaScript中创建打字机效果,这将考虑html标记规则
- 将c#视图模型转换为javascript模型时转义HTML标记
- Regex剥离具有特定属性的html标记
- 如何在不创建格式错误的HTML标记的情况下分解字符串
- HTML 标记未在 AngularJS ckEditor 中应用,而是在 Ediator 中显示 HTML 元素标记代码
- 如何在angularJS中运行for循环而不使用html标记
- Riot 每个构建 HTML 标记
- 用HTML标记+ 替换关闭的HTML标记
- 存储包含html标记的文本
- Regex以转义HTML标记
- 在html标记中序列化javascript代码
- JS来显示HTML标记