【发布时间】:2011-03-25 19:28:41
【问题描述】:
在视觉上突出显示页面上每个单词的最佳方式是什么,一次一个?我认为应该将单词分解成一个数组并以这种方式进行迭代,但是最好的方法是什么?
我已经知道如何执行字符串替换和设置单个元素的样式,诀窍是在页面上的每个单词上执行此操作,一次一个,以最有效的方式。
【问题讨论】:
标签: javascript html string highlighting
在视觉上突出显示页面上每个单词的最佳方式是什么,一次一个?我认为应该将单词分解成一个数组并以这种方式进行迭代,但是最好的方法是什么?
我已经知道如何执行字符串替换和设置单个元素的样式,诀窍是在页面上的每个单词上执行此操作,一次一个,以最有效的方式。
【问题讨论】:
标签: javascript html string highlighting
这是我的工作但未优化代码,它实现了一次突出显示每个单词以及在到达每行中的最后一个单词时滚动:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title></title>
<style type="text/css">
span.highlight {background-color:red;}
</style>
<script>
var height;
var width;
var spans = document.getElementsByTagName("span");
var i = 0;
var timePerChar = 100;
function getPositionOfElement(el) {
var elw = el.offsetWidth;
var elh = el.offsetHeight;
// yay readability
for (var lx=0, ly=0;
el != null;
lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent);
return {x: lx,y: ly,w: elw, h: elh};
}
function highlightElements() {
//alert(spans[i].innerHTML.length);
var highlightSpeed = timePerChar * spans[i].innerHTML.length;
spans[i].setAttribute("class", "highlight");
var objInfo = new Object();
var nxtObjInfo = new Object();
objInfo = getPositionOfElement(spans[i]);
nxtObjInfo = getPositionOfElement(spans[i+1]);
var amt = (objInfo.x + objInfo.w + 50);
console.log(amt);
console.log(width);
if(amt >= width && objInfo.x > nxtObjInfo.x){
console.log('SCROLL ' +objInfo.h+ ' ');
window.scrollBy(0,objInfo.h);
}
setTimeout('unHighlight()', highlightSpeed);
}
function unHighlight (){
spans[i].removeAttribute("class");
i++;
if(i < spans.length) {
highlightElements();
}
}
// This is just a namespace
var CIRRO = function(){
return {
/**
* Initialize the page behaviors
*/
init : function() {
CIRRO.wrapWordsWithSpan();
},
/**
* Replace the contents of each paragraph with span wrapped words
*/
wrapWordsWithSpan : function() {
var paragraphs = document.getElementsByTagName("p");
//alert(paragraphs.length);
if(!paragraphs ) return;
var j = 0;
while(j < paragraphs.length) {
// Parse the text into an array
var arr = paragraphs[j].innerHTML.split(" ");
// Generate span's for each item/word in the array
for( var i = 0; i < arr.length; i++ ) {
arr[i] = "<span>" + arr[i] + "</span>";
}
paragraphs[j].innerHTML = arr.join(" ");
//alert(paragraphs[j].innerHTML);
j++
}
}
};
}();
window.onload = CIRRO.init;
</script>
</head>
<body id="body">
<input type="button" onclick="highlightElements();" value="Get selected elements" />
<p>Test test test test test Test test test test test Test test test test test Test
test test test test Test test test test test Test test test test test Test test test test
test Test test test test test Test test test test test Test test test test test Test test
test test test Test test test test test Test test test test test Test test test test test
Test test test test test Test test test test test Test test test test test Test test test
test test</p>
<script>
var test = document.getElementById("body");
height = (test.clientHeight + 1);
width = (test.clientWidth + 1);
//alert(width +' '+ height);
</script>
</body>
</html>
【讨论】:
这实际上有点取决于文本。如果您在要替换的区域内有标签,我不怀疑innerHTML 上的正则表达式替换将无法正常工作。
类似这样的:
<p><strong>F</strong>irst letter of paragraph</p>
另一种方法是遍历 DOM 中的文本节点。如果您的目标不是 IE,则可以使用TreeWalker 轻松获取按文档顺序排列的文本节点集合。如果需要针对IE,这似乎是other ways to iterate text nodes的一个很好的总结
然后想法是遍历文本节点,对节点数据进行正则表达式拆分,并将每个子节点包装在一个带背景的跨度中以突出显示。
这是一个写得很仓促的例子,但它应该给你一个想法。
var iterator = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false),
template = document.createElement('span'),
span,
node,
text,
newNode;
template.style.backgroundColor = 'yellow';
while ((node = iterator.nextNode())) {
text = node.data.split(/\b/g);
for (var i = 0, len = text.length; i < len; i++) {
newNode = document.createTextNode(text[i]);
if (text[i].search(/\w+/) >= 0) {
span = template.cloneNode(false);
span.appendChild(newNode);
node.parentNode.insertBefore(span, node);
} else {
node.parentNode.insertBefore(newNode, node);
}
iterator.currentNode = newNode;
}
node.parentNode.removeChild(node);
}
这不是最快的可用方法,但它应该比在 innerHTML 上的正则表达式替换更准确。修改循环以使用 window.setTimeout 为突出显示设置动画也不是那么困难。
【讨论】:
这很简单。
<script type="text/javascript">
var str="ppshein is coldfusion developer.!";
document.write(str.replace("coldfusion", "<span style='background:orange;'>coldfusion8</span>"));
</script>
【讨论】:
您将需要获取某些内容的 innerHTML,然后将其拆分为空间,然后使用不同的类围绕每个单词包裹一个跨度,并将其设置回文本的位置。
使用 css 为这些着色或其他颜色。
我不确定您打算如何“一次一个”地突出显示它们。是否涉及动画或其他内容?
【讨论】: