MS Word 风格的符号对话框





3.00/5 (2投票s)
2004年8月26日
4分钟阅读

66826

3485
本文介绍了如何使用 JavaScript 为 Web 应用程序创建一个 MS Word 风格的符号对话框。
引言
如果您使用 Microsoft Word,您可能熟悉该符号对话框,它提供了许多符号供您插入到 Word 文档中。本文制作了类似的符号对话框,当您选择上面表格中列出的任何符号以插入到在线 HTML 编辑器创建的 HTML 文档中时,例如 Code Project Article Writer Helper,它将像真实对话框一样自动重新排列最近使用的符号的顺序。
本文还演示了使用 XMLHTTP 刷新 Web 页面的部分内容,这要归功于 Dhandapani Ammasai 的精彩文章 Refresh Portion Of Your Web Page Using XMLHTTP,您应该先阅读。
用于存储符号的数据结构
本文使用 XML 文档来存储符号表中的符号。XML 文档的 DTD 如下所示
<!ELEMENT Symbols (Symbol)>
<!ELEMENT Symbol (SymName,SymCode)>
<!ELEMENT SymName (#PCDATA)>
<!ELEMENT SymCode (#PCDATA)>
<!ELEMENT SymUseTimes (#PCDATA)>
<!ATTLIST Symbol SymID CDATA #REQUIRED>
每个 Symbol
元素有一个名为 SymID
的属性,三个子元素:SymName
元素指定符号的名称,SymCode
指定与符号对应的 ANSI 字符代码,SymUseTimes
表示该符号被拾取并插入到其他文档中的次数。
使用上述 DTD 指定的内容模型,可以创建用于保存符号的 XML 文档,其片段如下所示
<?xml version='1.0' encoding='gb2312' ?>
<Symbols>
<Symbol SymID="1">
<SymName>℃</SymName>
<SymCode>-24090</SymCode>
<SymUseTimes>0</SymUseTimes>
</Symbol>
<Symbol SymID="2">
<SymName>$</SymName>
<SymCode>-24089</SymCode>
<SymUseTimes>0</SymUseTimes>
</Symbol>
<Symbol SymID="3">
<SymName>‰</SymName>
<SymCode>-24085</SymCode>
<SymUseTimes>0</SymUseTimes>
</Symbol>
</Symbols>
工作原理
当用户请求打开符号对话框的网页时,服务器端 VBScript 会调用函数来创建符号表和最近使用的符号列,然后显示对话框。当触发 ondblclick
事件时,客户端 JavaScript 将调用函数,使用 XMLHTTP 更新与所选符号相关的特殊符号元素,并排列最近使用的符号的顺序。
服务器端 VBScript 代码
VBScript 包含三个函数。
首先,MakeSymbolTable(xmlFile)
函数从 XML 文档中提取一组符号并以表格形式显示它们。
Sub MakeSymbolTable(xmlFile)
'/* some variables used in this procdure */
dim xmlDoc
dim oSymbols,oSymbol
dim strXPath,strSymID,strSymbol
dim intCount,intLoop,intFlag
dim strFullPathFile
'/* Load the XML document which store the symbols */
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.validateOnParse=False
strFullPathFile = server.MapPath(xmlFile)
xmlDoc.load(strFullPathFile)
'/* Firstly, get the list of all nodes named Symbol */
'/* Then access every node in the collection */
'/* and get information what we need from the node */
'/* Finally, show them in a table */
strXPath = "//Symbol"
set oSymbols = xmlDoc.documentElement.selectNodes(strXPath)
intCount = oSymbols.length
intFlag = 0
for intLoop=0 to intCount-1
set oSymbol = oSymbols.item(intLoop)
strSymID = oSymbol.getAttribute("SymID")
strSymbol = chr(oSymbol.selectSingleNode("SymCode").text)
%>
<td><div class="clsBlockItemU" xType="Update" xID="<%=strSymID%>">
<%=strSymbol%></div></td>
<%
intFlag = intFlag + 1
if(intFlag=6) then
intFlag = 0%>
<td class="clsNoBorder"></TD>
</tr>
<tr>
<%
End if
Next
End Sub
接下来是 ShowRUSymbols(xmlFile,xslFile)
函数,它选择最近使用的符号,并以列的形式显示它们。
Sub ShowRUSymbols(xmlFile,xslFile)
'/* some variables used in this procdure */
dim xmlDoc,xslDoc,xmlRstDoc
dim oSymbols,oSymbol
dim strXPath,strSymID,strSymbol
dim intCount,intLoop,intFlag
dim strFullPathXmlFile,strFullPathXslFile
'/* Load the XML document which store the symbols */
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.validateOnParse=False
strFullPathXmlFile = server.MapPath(xmlFile)
xmlDoc.load(strFullPathXmlFile)
'/* Load the XSL document which is used to sort the XML document */
Set xslDoc = CreateObject("Msxml2.DOMDocument")
xslDoc.async = False
xslDoc.validateOnParse=False
strFullPathXslFile = server.MapPath(xslFile)
xslDoc.load(strFullPathXslFile)
'/* Sorting the XML document with the XSLT document */
Set xmlRstDoc = CreateObject("Msxml2.DOMDocument")
xmlRstDoc.async = False
xmlRstDoc.validateOnParse=False
xmlDoc.transformNodeToObject xslDoc, xmlRstDoc
strXPath = "//Symbol"
set oSymbols = xmlRstDoc.documentElement.selectNodes(strXPath)
intCount = oSymbols.length
if(intCount <14) then
intSCount = intCount
else
intSCount = 14
End if
intFlag = 0
for intLoop=0 to intCount-1
set oSymbol = oSymbols.item(intLoop)
strSymID = oSymbol.getAttribute("SymID")
strSymbol = chr(oSymbol.selectSingleNode("SymCode").text)
%>
<td><div class="clsBlockItemU" xType="noUpdate" xID="<%=strSymID%>">
<%=strSymbol%></div></td>
<%
Next
End Sub
最后一个过程是 IncUseTimes(strSymID,xmlFile)
函数,它选择 SymID
属性值等于输入参数 strSymID
值的相应 Symbol
元素 (Ele
),获取其名为 SymUseTimes
的子元素的文本内容,然后将字符串转换为数字 (num
),并在数字上加 1,最后将 Ele
元素的名为 SymUseTimes
的子元素的文本内容设置为数字 num
。
Sub IncUseTimes(strSymID,xmlFile)
'/* some variables used in this procdure */
dim xmlDoc
dim oItem
dim strXPath,strSymUsedTimes
dim lngCount
dim strFullPathFile
'/* Load the XML document which store the symbols */
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.validateOnParse=False
strFullPathFile = server.MapPath(xmlFile)
xmlDoc.load(strFullPathFile)
'/* Select the corresponding SymUseTimes element */
'/* then, Get the text content of the element */
'/* Convert the string to a number, and increase the number by 1 */
'/* Set the text content of the element to the new number's value */
'/* Save the XML document */
strXPath = "//Symbol[@SymID='"& strSymID & "']/SymUseTimes"
set oItem = xmlDoc.documentElement.selectNodes(strXPath)
strSymUsedTimes = oItem.text
lngCount = Clng(strSymUsedTimes) + 1
oItem.text = Cstr(lngCount)
xmlDoc.save strFullPathFile
End Sub
客户端 JavaScript 代码
JavaScript 包含六个函数。这些函数的关系描述如下
当触发 dblclick
事件时,会调用 doSel()
函数。此函数很简单,它检查是否已选择了一个符号项;如果为真,则调用 UpdateDB()
函数更新相应的符号元素。在 UpdateDB()
函数的体内,FinishUpdate()
函数将与 onreadystatechange
事件关联。当应用程序中的 onreadystatechange
事件触发时,将调用 FinishUpdate()
函数来决定是否更新最近使用的符号。如果需要,FinishUpdate()
函数将调用 UpdateMostUse()
函数来更新用户界面。
UpdateDB()
函数和 UpdateMostUse()
函数比其他函数稍微复杂一些,让我们详细讨论它们,开始吧
首先,我声明了一些全局变量,因为它们中的每一个几乎都在所有函数中使用。
/* store a collection of symbol */
var arrSymbol = new Array(14);
/* store a collection of symbol's ID */
var arrSymID = new Array(14);
/* for storing the current selected item */
var gCurDivSel = null;
/* for storing an XMLHTTP object */
var http = null;
UpdateDB()
函数使用 XMLHTTP 在 Web 服务器上更新数据。
function UpdateDB(xID){
/* some variables used in this function */
var strFileName = "IncSymUseTimes.asp?id="+xID;
var editdata = null;
/* Communicate with the Web server using XMLHTTP */
http = new ActiveXObject(" Microsoft.XMLHTTP");
http.open("POST",strFileName,true);
/* Bind the FinishUpdate() function to the onreadystatechange event */
http.onreadystatechange = FinshUpdate;
http.send(editdata);
}
UpdateMostUse()
函数用于重新排列最近使用的符号,使用 DHTML 更新用户界面,而无需刷新整个页面。
function UpdateMostUse(oDiv){
/* some variables used in this function */
var nLoop = 0;
var nCount = arrSymbol.length;
var nIndex = -1;
var chrCurUse,nSymID;
var chrTmp,nTmp;
var oDivCur = null;
var oTD = null;
/* arrange the symbol array */
chrCurUse = oDiv.innerText;
nSymID = oDiv.xID;
for(nLoop=0;nLoop<nCount;nLoop++)
{
chrTmp = arrSymbol[nLoop];
if(chrTmp==chrCurUse)
nIndex = nLoop;
}
if(nIndex!=-1){
chrTmp = arrSymbol[0];
nTmp = arrSymID[0];
arrSymbol[0]=arrSymbol[nIndex];
arrSymID[0] = arrSymID[nIndex];
arrSymbol[nIndex] = chrTmp;
arrSymID[nIndex] = nTmp;
}
else{
arrSymbol.pop();
arrSymbol.unshift(chrCurUse);
arrSymID.pop();
arrSymID.unshift(nSymID);
}
/* update the user interface using DHTML */
for(nLoop=0;nLoop<nCount;nLoop++){
oTD = trMostUsed.cells[nLoop];
oDivCur = oTD.firstChild;
if(typeof(oDivCur)=="object"){
oDivCur.innerText=arrSymbol[nLoop];
oDivCur.xID=arrSymID[nLoop];
}
}
}
如何使用它
- 下载源文件并解压到 Web 服务器的 Web 目录中。为 XML 文件夹设置读写访问权限。
- 将如下所示的代码复制到您的 Web 页面中。
function OpenSymDlg(){ /* some variables used in this function */ var strOptions,strUrl; /* Configure the window omaments of the dialog box */ /* and then Create a modeless dialog box that displays the specified Web Page */ strOptions = "status:no;dialogHeight:346px;dialogWidth:446px;resizable:no;help:no;" strUrl = "SymbolDialog.asp"; window.showModelessDialog(strUrl,null,strOptions); }
- 将
ShowSymDlg()
函数绑定到一个事件,该事件在调用该函数时会在任何对象上触发。<input type="button" onclick="OpenSymDlg()" value="Open Symbol Dialog">
- 触发选定对象的事件以显示符号对话框。
结论
本文创建了一个 MS Word 符号对话框,如您所见,它似乎运行正常。希望您觉得它有所帮助。
请随时发送您的评论、建议和问题到:marryjack@hotmail.com。