我在 javascript 中编写了一个自定义搜索来突出显示文本。
方案是获取innerHtml
并搜索文本并突出显示它们。
问题:如果用户在 我 中搜索 i 找到<div>
标签,一切都搞砸了。
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;
答案 0 :(得分:2)
一种可能的解决方案是使用节点:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: #222222;
}
canvas {
background-color: #000000;
width: 25%;
height: 400px;
}
</style>
</head>
<body>
<canvas id="mainCanvas"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("mainCanvas");
var context = canvas.getContext("2d");
var keys = [];
var speed = 4;
// var width = 25%;
var height = 400;
window.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
}, false);
window.addEventListener("keyup", function(e) {
delete keys[e.keyCode];
}, false);
var player = {
x: 10,
y: 10,
width: 30,
height: 30
};
function game() {
update();
render();
}
function update() {
if (keys[40]) player.y++ * speed;
if (keys[38]) player.y-- * speed;
if (keys[37]) player.x-- * speed;
if (keys[39]) player.x++ * speed;
}
function render() {
context.clearRect(0, 0, (canvas.width * 0.25), height);
context.fillStyle = "white";
context.fillRect(player.x, player.y, player.width, player.height);
}
setInterval(function() {
game();
}, 1000/30);
</script>
</body>
</html>
子节点(而不是body
)这是一个示例函数,它将突出显示您指定的文本:
innerHTML
这是一个示例演示(也可在此JSFiddle上找到):
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);
}
}
}
&#13;
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");
&#13;
此解决方案的一个问题是它添加了包含搜索字符串的每个文本节点的其他<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>
元素(尽管我不知道可能给您带来多大的不便)。它也是递归的,你可能想要研究一个迭代的替代方案。
UPDATE。我知道你没有要求这个,但我认为这可能很有趣:通过重新排序参数列表,并在第一次调用时添加一些初始化,你可以制作为用户提供的功能清理器,同时添加一些有趣的功能:
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");
你可以看到一个关于这个JSFiddle的演示:http://jsfiddle.net/tkm5696w/2/
答案 1 :(得分:1)
您可以使用innerText
代替innerHTML
。
您可以使用element.textContent
。
innerText
和textContent
之间的差异可以在以下链接中。
Internet Explorer介绍了element.innerText
。意图相似,但有以下不同之处:
答案 2 :(得分:0)
innerHtml将搜索给定元素中的文本和元素。使用innerText或textContent只搜索文本(我明白这就是你想要的)