|
<!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=gb2312" /> |
|
<title>关键字快速搜索</title>
|
|
<style> |
|
body |
|
{ |
|
font-size: 14px; |
|
} |
|
|
|
h3 |
|
{ |
|
display: inline; |
|
margin: 0; |
|
} |
|
|
|
#spnKeyNum, #spnWordNum |
|
{ |
|
color: #F00; |
|
} |
|
|
|
#spnList a |
|
{ |
|
font-size: 12px; |
|
color: #0000FF; |
|
} |
|
|
|
#spnTime |
|
{ |
|
color: #600; |
|
} |
|
|
|
textarea, #divDisplay |
|
{ |
|
margin: 0; |
|
padding: 0; |
|
font-size: 14px; |
|
display: block; |
|
background: #EEE; |
|
border: #999 solid 1px; |
|
} |
|
|
|
#txtKeys |
|
{ |
|
width: 95%; |
|
height: 100px; |
|
} |
|
|
|
#txtContent, #divDisplay |
|
{ |
|
height: 400px; |
|
width: 95%; |
|
} |
|
|
|
#divDisplay |
|
{ |
|
display: none; |
|
overflow: auto; |
|
} |
|
|
|
#divDisplay em |
|
{ |
|
color: #F00; |
|
font-style: normal; |
|
} |
|
|
|
#divFoot |
|
{ |
|
padding: 5px; |
|
width: 95%; |
|
} |
|
|
|
#spnLable2 |
|
{ |
|
margin: 5px; |
|
float: left; |
|
color: #690; |
|
} |
|
|
|
button |
|
{ |
|
float: left; |
|
} |
|
|
|
#desc |
|
{ |
|
color: #333; |
|
float: right; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body onload="handleLoad();"> |
|
<div id="divTop"> |
|
<h3>关键字</h3>
|
|
<span id="spnLable1">(<span id="spnKeyNum">0</span>个)</span>
|
|
<span id="spnList">
|
|
<a href="javascript:load('city.txt');">世界城市</a>
|
|
<a href="javascript:load('words.txt');">部分英文单词</a>
|
|
<a href="javascript:load('idiom.txt');">成语全集</a>
|
|
</span>
|
|
</div> |
|
<div id="divMain"> |
|
<textarea id="txtKeys" onchange="handleKeyChange();"></textarea>
|
|
<h3>内容</h3>
|
|
<span id="spnLable1">(<span id="spnWordNum">0</span>字)</span>
|
|
<textarea id="txtContent" onchange="handleContentChange();"></textarea>
|
|
<div id="divDisplay"></div>
|
|
</div> |
|
<div id="divFoot"> |
|
<span id="spnLable2">搜索用时: <span id="spnTime">0</span>ms</span>
|
|
<button id="btnStart" onclick="handleClick();"> 测试</button>
|
|
<button id="btnReset" onclick="reset()" disabled="disabled"> 重置</button>
|
|
<span id="desc">EtherDream 2009</span>
|
|
</div> |
|
|
|
<script> |
|
var tblRoot; |
|
|
|
/* |
|
* 函数: makeTree |
|
* 注释: 将关键字生成一颗树 |
|
*/ |
|
function makeTree() |
|
{ |
|
var strKeys = objKeys.value; |
|
var arrKeys = strKeys.split(""); |
|
var tblCur = tblRoot = {}; |
|
var key; |
|
|
|
for(var i=0,n=arrKeys.length; i<n; i++) |
|
{ |
|
key = arrKeys[i]; |
|
|
|
if(key == ';') //完成当前关键字 |
|
{ |
|
tblCur.end = true; |
|
tblCur = tblRoot; |
|
continue; |
|
} |
|
|
|
if(key in tblCur) //生成子节点 |
|
tblCur = tblCur[key]; |
|
else |
|
tblCur = tblCur[key] = {}; |
|
} |
|
|
|
tblCur.end = true; //最后一个关键字没有分割符 |
|
} |
|
|
|
/* |
|
* 函数: search |
|
* 注释: 标记出内容中关键字的位置 |
|
*/ |
|
function search(content) |
|
{ |
|
var tblCur; |
|
var i = 0; |
|
var n = content.length; |
|
var p, v; |
|
var arrMatch = []; |
|
|
|
while(i < n) |
|
{ |
|
tblCur = tblRoot; |
|
p = i; |
|
v = 0; |
|
|
|
for(;;) |
|
{ |
|
if(!(tblCur = tblCur[content.charAt(p++)])) |
|
{ |
|
i++; |
|
break; |
|
} |
|
|
|
if(tblCur.end) //找到匹配关键字 |
|
v = p; |
|
} |
|
|
|
if(v) //最大匹配 |
|
{ |
|
arrMatch.push(i-1, v); |
|
i = v; |
|
} |
|
} |
|
|
|
return arrMatch; |
|
} |
|
</script> |
|
|
|
<script> |
|
var $ = function(id){return document.getElementById(id)}; |
|
|
|
var objKeys = $("txtKeys"); |
|
var objContent = $("txtContent"); |
|
var objDisplay = $("divDisplay"); |
|
var bKeyChanged = false; |
|
|
|
|
|
function handleKeyChange() |
|
{ |
|
var str = objKeys.value; |
|
var n; |
|
|
|
if(str.length==0) |
|
n = 0; |
|
else |
|
n = str.split(";").length; |
|
|
|
/* |
|
* 显示关键字数量 |
|
*/ |
|
$("spnKeyNum").innerHTML = n; |
|
|
|
bKeyChanged = true; |
|
} |
|
|
|
function handleContentChange() |
|
{ |
|
/* |
|
* 显示内容长度 |
|
*/ |
|
$("spnWordNum").innerHTML = objContent.value.length; |
|
} |
|
|
|
function handleLoad() |
|
{ |
|
handleKeyChange(); |
|
handleContentChange(); |
|
} |
|
|
|
function handleClick() |
|
{ |
|
var strContent = objContent.value; |
|
var arrMatch; |
|
var arrHTML = []; |
|
var strHTML; |
|
var mid; |
|
var p = 0; |
|
|
|
|
|
$("btnStart").disabled = true; |
|
$("btnReset").disabled = false; |
|
|
|
if(bKeyChanged) |
|
{ |
|
makeTree(); |
|
bKeyChanged = false; |
|
} |
|
|
|
/* |
|
* 开始搜索! |
|
*/ |
|
var t = +new Date(); |
|
|
|
arrMatch = search(strContent); |
|
|
|
/* |
|
* 搜索用时 |
|
*/ |
|
$("spnTime").innerHTML = +new Date() - t; |
|
|
|
/* |
|
* 标记关键字 |
|
*/ |
|
for(var i=0,n=arrMatch.length; i<n; i+=2) |
|
{ |
|
mid = arrMatch[i]; |
|
arrHTML.push(strContent.substring(p, mid), |
|
"<em>", |
|
strContent.substring(mid, p = arrMatch[i+1]), |
|
"</em>"); |
|
} |
|
arrHTML.push(strContent.substring(p)); |
|
|
|
strHTML = arrHTML.join("").replace(/\n/g, "<br>"); |
|
|
|
/* |
|
* 显示结果 |
|
*/ |
|
objDisplay.innerHTML = strHTML; |
|
|
|
objContent.style.display = "none"; |
|
objDisplay.style.display = "block"; |
|
} |
|
|
|
function reset() |
|
{ |
|
$("btnStart").disabled = false; |
|
$("btnReset").disabled = true; |
|
|
|
objContent.style.display = "block"; |
|
objDisplay.style.display = "none"; |
|
} |
|
|
|
function load(file) |
|
{ |
|
/* |
|
* 创建HTTP组件 |
|
*/ |
|
if(window.ActiveXObject) |
|
{ |
|
objHttp = new ActiveXObject("Microsoft.XMLHTTP"); |
|
} |
|
else |
|
{ |
|
objHttp = new XMLHttpRequest(); |
|
objHttp.overrideMimeType("text/xml"); |
|
} |
|
|
|
objHttp.onreadystatechange = function() |
|
{ |
|
if(objHttp.readyState != 4) |
|
return; |
|
|
|
objKeys.value = objHttp.responseText; |
|
handleKeyChange(); |
|
}; |
|
|
|
/* |
|
* 发送请求 |
|
*/ |
|
objHttp.open("GET", file, true); |
|
objHttp.send(null); |
|
} |
|
|
|
</script> |
|
</body> |
|
</html> |
|
|