|
济南大众日报社信息中心
王 飞
---- 微 软 公 司 推
出的IE4.X, 使 得 按 照HTML4 标 准 制 作 的 网 页 一 时 成 为 时 尚,这 类 网 页 在 动 态 功 能 方 面 有 了 非 常 大
的 提 高。 特 别 是可 以 通 过 页 面 内 嵌 的Script 语 句, 使 页 面 中 的 任 意 一 段文 字 可 以 在 需 要 时 显 示 出
来, 在 不 需 要 时 隐 藏 起 来,利 用 这 一 特 性, 就 可 以 在 页 面 上 设 计 出 可 以 伸 缩 的 层次 列 表 出 来。 这 种
列 表 实 际 表 现 的 是 一 种 分 层 次 的 树状 结 构, 读 者 可 以 用 鼠 标 点 击 上 一 层 的 条 目, 而 展 开或 收 起 它
的 下 一 层。 在 明 白 了HTML4 标 准 中DOM 的 实 现 机 制及 对 风 格 表 单 的 定 义 之 后, 很 容 易 可 以 找 到 实 现
这 种列 表 的 途 径。 但 是 一 般 来 说, 这 种 列 表 的 条 目 都 比 较多, 如 果 每 次 都 用 手 工 制 作, 不 仅 非 常 烦
琐, 而 且 也十 分 容 易 出 错, 所 以 要 真 正 应 用 到 实 际 的 页 面 制 作 当中, 还 必 须 有 一 种 比 较 自 动 的 方
法。 本 人 通 过 实 验,用ASP 方 式 完 成 了 一 种 比 较 通 用 的 实 现 过 程, 稍 加 变 化就 可 以 应 用 到 各 种 主 页
的 制 作 过 程 当 中, 非 常 方 便。
---- 简 单 的 实 现
---- 要 在 网 页 上 实现 伸
缩, 首 先 要 清 楚 如 何 使 页 面 中 的 一 段 文 字 按 需 要隐 藏 和 显 示 出 来。 我 们 看 下 面 这 段HTML 格 式 的 片
段:
< Div Id="test" Style="Display:none" >
要 隐 藏 的 文 字< /Div >
---- 这 是 符 合HTML4
标准 的HTML 语 句, 夹 在< Div > 之 间 的 文 本 将 不 显 示 在 页面 上, 因 为 它 风 格 表 单 的Display 属 性
为none。( 由 于 本 文不 主 要 介 绍HTML4 的 风 格 表 单, 有 关 祥 情 请 读 者 查 找 相关 资 料。) 只 要 能 动 态 地
将Display 属 性 设 为 空, 即 缺 省值, 那 么 这 段 文 字 就 可 以 动 态 地 被 显 示 出 来。 这 需 要Script 的 支
持, 下 面 就 是 一 个 让 上 面 那 样 的 文 字 显 示 和 隐 藏起 来 的 两 个JavaScript 函 数, 只 要 将 自 定 义
的Div 的Id 值 代入, 对 应 的 文 字 就 显 示 或 隐 藏 起 来 了:
< script language="JavaScript" >
function ShowDiv(DivId)
{
document.all[DivId].style.display='';
return 0;
}
< /script >
function HideDiv(DivId)
{
document.all[DivId].style.display='none';
return 0;
}
< /script >
---- 有 了 这 两 个 函数,
就 要 考 虑 在 什 么 时 候 调 用 它 们。 熟 悉Script 编 程 的读 者 当 然 已 经 想 到, 可 以 把 它 们 放 到 事 件 响 应
过 程 之中 了。 大 体 的 形 式 可 能 是 这 样:
< a href="#" onclick="return ShowDiv('test');" >显示< /a >
< a href="#" onclick="return HideDiv('test');" >隐藏< /a >
---- 将 上 面 的 片 段组 合
到 一 个HTML 文 件 中, 也 算 是 一 个 完 整 的 例 子 了, 用IE4 试 验 一 下, 看 看 是 否 达 到 了 预 期 的 效 果。(
注 意:JavaScript 是 大 小 写 敏 感 的, 排 版 时 可 能 出 现 差 错, 实 际 应 用中, 最 好 都 用 小 写。)
---- 有 了 以 上 的 了解,
制 作 一 个 伸 缩 式 的 层 次 列 表, 只 是 由 简 到 繁 的 过程, 所 以 我 也 就 不 必 做 什 么 解 释, 只 提 供 一 个 例
子 做为 参 考, 这 个 例 子 也 是 我 们 下 一 步 要 用 程 序 来 实 现 的一 个 结 果:
文 件 名:LsTest.htm
< html >
< head >
< title >DyList Test< /title >
< script language="JavaScript" >
/*
根据对象当前的属性,改变对象的显示状态
*/
function OnClickDiv(DivId)
{
if(document.all[DivId].style.display=='none')
{ document.all[DivId].style.display=''; }
else
{ document.all[DivId].style.display='none'; }
return 0;
}
< /script >
< /head >
< body >
< h3 >List Start< /h3 >< hr >
< Div Id="dy1" Style=display: >< ul >
< li >< a href="#" onclick="return
OnClickDiv('dy2')") >国内报刊< /a >
< Div Id="dy2" Style=display:none >< ul >
< li >< a href="http://www.peopledaily.com.cn" >
人民日报< /a >
< li >< a href="http://www.gmdaily.com.cn" >
光明日报< /a >
< li >< a href="#" onclick="return
OnClickDiv('dy3')") >大众日报< /a >
< Div Id="dy3" Style=display:none >< ul >
< li >< a href="http://www.dzdaily.com.cn" >
大众日报< /a >
< li >< a href="http://www.dzdaily.com.cn/ncdz.htm" >
农村大众< /a >
< li >< a href="http://www.dzdaily.com.cn/qlwb.htm" >
齐鲁晚报< /a >
< li >< a href="http://www.dzdaily.com.cn/shrb.htm" >
生活日报< /a >
< /ul >< /div >
< /ul >< /div >
< li >< a href="#" onclick="return OnClickDiv('dy4')") >
搜索引擎< /a >
< Div Id="dy4" Style=display:none >< ul >
< li >< a href="http://gbchinese.yahoo.com" >
雅虎< /a >
< li >< a href="http://www.sohoo.com.cn" >
搜狐< /a >
< /ul >< /div >
< /ul >< /div >
< hr >< h3 >List End< /h3 >
< /body >
< /html >
---- 实 现 自 动 化
---- 上 面 的 一 大 堆东
西, 谁 看 了 都 会 眼 花 缭 乱 的。 不 过 在IE4 上 浏 览 的 效果, 又 确 实 酷 得 让 人 心 痒, 所 以 费 一 点 力 气, 用
程 序将 这 一 烦 琐 的 制 作 过 程 自 动 化 一 下, 是 完 全 值 得 的。一 个 简 单 的 思 路: 将 树 状 层 次 结 构 的 数 据
保 存 到 一 个简 洁 的 文 件 载 体 当 中, 写 一 段 通 用 的 程 序 从 载 体 文 件中 读 取 数 据, 生 成 我 们 所 要
的HTML 文 件。 那 么 头 一 步 是要 选 择 什 么 样 的 载 体 啦, 数 据 库 方 式 当 然 最 值 得 考虑, 但 这 将 牵 扯 出 一
大 堆 的 问 题, 我 想 还 是 在 另 一 个专 题 里 来 讨 论 吧, 在 这 里 我 选 择 了Windows 平 台 上 常 用 的.ini 文
件, 这 种 文 件 很 适 合 于 保 存 树 状 的 层 次 数 据, 并 且系 统 平 台 已 经 提 供 了 基 本 的 操 作 函 数, 可 以 大
大 省 些力 气。
---- 我 把 这 一 过 程制 成
了ASP(Active Server Page) 的 形 式, 这 样 拿 过 来 就 可 以 直接 使 用 了, 当 然 有 时 还 是 需 要 静 态
的HTML 文 件, 那 么 可以 把ASP 中 的 代 码 转 移 到VB 程 序 中, 也 并 不 困 难。 为 了 能在ASP 中 处 理.ini 文
件, 用 到 了 我 以 前 写 的 一 个ActiveX 服 务对 象, 这 个 服 务 对 象 将 对.ini 文 件 操 作 的 各 种 函 数 函 数封
装 在 一 个 类(class) 中, 我 用 起 来 已 经 有 顺 手 了, 下 面开 始 我 们 的 程 序 设 计 吧, 先 来 看 一 下 树 状 的
层 次 数 据保 存 在.ini 文 件 中 的 形 式:
文 件 名:LsTest.ini
[root]
a= 国 内 报 刊
b= 搜 索 引 擎
[a]
a1= 人 民 日 报,http://www.peopledaily.com.cn
a2= 光 明 日 报,http://www.gmdaily.com.cn
a3= 大 众 日 报
[a3]
a3_1= 大 众 日 报,http://www.dzdaily.com.cn/
a3_1= 农 村 大 众,http://www.dzdaily.com.cn/ncdz.htm
a3_1= 齐 鲁 晚 报,http://www.dzdaily.com.cn/qlwb.htm
a3_1= 生 活 日 报,http://www.dzdaily.com.cn/shrb.htm
[b]
b1= 雅 虎,http://gbchinese.yahoo.com
b2= 搜 狐,http://www.sohoo.com.cn
---- 文 件 中 表 现 出的 树
状 层 次 关 系 非 常 明 显, 你 只 要 稍 微 花 点 心 思 就 一定 能 够 明 白 了。 这 里 我 做 了 一 个 小 小 的 约 定, 就
是 每一 个 条 目 的 等 号 后 面, 首 先 是 这 个 条 目 的“ 标 题”,它 是 不 应 省 略 的。 之 后 是 该 条 目 的 超 级 链 接
地 址, 由一 个 逗 号 进 行 分 隔, 如 果 没 有 地 址, 就 表 明 它 还 有 下一 层 的 子 条 目。
---- 要 在ASP 程 序 中使
用 自 制 的ActiveX 服 务 对 象, 首 先 要 把 该 服 务 程 序 安 装到ASP 程 序 运 行 的 机 器 上, 然 后 在ASP 程 序
中 建 立 这 个 对象, 我 想 这 些 大 家 一 定 也 有 些 经 验 了, 这 里 就 不 多 说了。 那 么 列 出 一 个 主 题 中 的 所 有
子 条 目, 大 概 的 形 式就 如 下 面 的 样 子:
Set Prof = Server.CreateObject("vbProFile.ProFile")
Prof.FileName = proPath
Buf = Prof.FirstValue(" 主 题 名")
Do While Len( Buf ) > 0
... ...
Buf = Prof.NextValue()
Loop
---- 在 上 面 的循 环
中,Buf 中 接 收 的 数 据 是 这 样 的 一 种 形 式:“ 条 目名= 条 目 标 题, 链 接 地 址”, 为 了 便 于 在 程 序 中 使
用,用InitDyItemStr 函 数 将 字 符 串 分 解 到 定 义 好 的 全 局 变 量 当中:
< !--#INCLUDE FILE="Str.inc"-- >
< %
gDyItemName="" ' 当 前 条 目 的 名 称
gDyItemTitle="" ' 当 前 条 目 的 标 题
gDyItemLink="" ' 当 前 条 目 的 链 接 地 址
Sub InitDyItemStr( s )
gDyItemName = StrHead(s, "=")
gDyItemTitle = StrHead(s, ",")
gDyItemLink = s
End Sub
% >
---- 这 里 调 用 了
一个StrHead 函 数, 这 个 函 数 也 是 出 自 本 人 之 手, 在 处 理 字符 串 时 十 分 有 用, 是 我 在 编 程 时 使 用 频
率 最 高 的 函 数之 一。 另 外 为 了 方 更 地 在 程 序 中 输 出 引 号, 就 写 了 一个 专 门 在 字 符 串 两 端 加 上 引 号
的 函 数, 因 为 在 编 写ASP 程 序 时 常 常 要 调 用 这 两 个 函 数, 所 以 我 单 独 把 他 们 放在 一 个 文 件 中, 在 要
使 用 时 把 这 个 文 件 包 含 进 行 就 可以 了, 下 面 就 是 这 个 文 件:
文 件 名:Str.inc
< %
' 在 第 一 次 遇 参 数c 的 位 置 载 取ss
' 返 回 载 取 的 前 半 载,ss 中 保 留 后 半 载
' 当ss 中 不 包 含c 时, 相 当 于 从ss 的 最 后 载 取
Public Function StrHead(ss, c)
i = InStr(ss, c)
If i > 0 Then
StrHead = Mid(ss, 1, i - 1)
ss = Mid(ss, i + Len(c))
Else
StrHead = ss
ss = ""
End If
End Function
' 在s 的 两 端 加 上 引 号 返 回
Public Function YH(s)
YH = Chr(34) & s & Chr(34)
End Function
% >
---- 在 响 应OnChick
事件 时, 为 书 写 简 单, 可 以 先 写 成 一 个JavaScript 函 数, 以 备调 用( 注 意: 这 里 的Java Script 函 数
是 在 浏 览 器 上 执 行的, 一 定 要 与 服 务 器 端 执 行 的 代 码 区 分 开 来):
< script language="JavaScript" >
function OnClickDiv(DivId)
{
if(document.all[DivId].style.display=='none')
{ document.all[DivId].style.display=''; }
else
{ document.all[DivId].style.display='none'; }
return 0;
}
< /script >
---- 为 了 给 每 一 个条 目
在 页 面 上 建 立 一 个 唯 一 的ID 值, 以 便 在 事 件 处 理过 程 中 进 行 操 作, 所 以 定 义 了 一 个 全 局 的 计 数 器
和 一个ID 构 造 函 数:
< %
curDyItemIndex=0
Function DyItemId()
DyItemId="dy" & curDyItemIndex
End Function
% >
---- 有 了 这 些 准 备工
作, 最 后 的 输 出 就 不 难 了, 提 炼 一 下 我 们 要 完 成 的任 务, 就 在 从LsTest.ini 文 件 中 读 取 数 据, 输 出
如LsTest.htm 文件 中 的 格 式 数 据。 由 于 数 据 是 树 状 的, 所 以 很 自 然 地会 使 用 上 函 数 的 递 归, 请 看 下
面 实 现 的 主 体 函 数:
Sub ListItems(proPath,ItemName,Disp)
'建立并初始化ProFile对象
Set ItemProf = Server.CreateObject("vbProFile.ProFile")
ItemProf.FileName = proPath
'开始一个DIV对象,包含所有的子条目在其中
Response.Write "< Div Id=" & YH(DyItemId) & _
" Style=display:" & Disp & " >< ul >" & vbCrLf
'开始输出每一个子条目
buf = ItemProf.FirstValue(ItemName)
Do While Len(buf) > 0
InitDyItemStr buf
If Len(gDyItemLink) > 0 then
Response.Write "< li >< a href=
" & YH(gDyItemLink) & " >" & _
gDyItemTitle & "< /a >" & vbCrLf
Else
'如果链接地址为空,则开始下一层的列表
curDyItemIndex = curDyItemIndex + 1
Response.Write "< li >
< a href=" & YH("#") & _
" onclick=" & YH("return OnClickDiv
('" & DyItemId & "')") & _
") >" & gDyItemTitle & "< /a >" & vbCrLf
ListItems proPath,gDyItemName,"none" '使用递归
End If
buf=ItemProf.NextValue()
Loop
'结束定义的DIV对象
Response.Write "< /ul >< /div >" & vbCrLf
End Sub
最后为了调用方便,再定义一个对外的接口函数:
Public Sub DyList(proName,rootItem)
'将逻辑路径映射成物理路径
proPath=Server.mappath(proName)
curDyItemIndex = curDyItemIndex + 1
ListItems proPath,rootItem,""
End Sub
---- 把 上 面 这些 片
段 保 存 到 一 个 文 件 中, 文 件 名 就 叫dyList.inc 吧, 我们 就 算 大 功 告 成 了, 你 是 不 是 想 马 上 看 看 效
果 呢 ? 用下 面 这 个ASP 文 件 来 做 一 下 实 验, 瞧 瞧 你 是 否 满 意 ?
文 件 名:LsTest.htm
< html >
< head >
< title >DyList Test< /title >
< !--#INCLUDE FILE=" dyList.inc"-- >
< /head >
< body >
< h3 >List Start< /h3 >< hr >
< %
DyList "lsTest.ini","root"
% >
< hr >< h3 >List End< /h3 >
< /body >
< /html >
---- 走 向 完 善
---- 功 能 是 实 现了, 但
在 美 观 程 度 上 还 不 能 尽 人 意, 不 过 这 是 让 每 个人 施 展 各 自 绝 活 的 时 候, 我 可 就 不 便 包 办 了。 这 里
我只 提 出 几 个 我 想 到 的 改 进 方 式, 供 大 家 参 考:
---- 通 过 响
应onmouseover 和onmouseout 两 个 事 件, 可 以 做 到 当 鼠 标 移 到 某 一 个 条 目上 时, 令 其 变 成 与 众 不
同 的 颜 色, 这 功 能 实 现 起 来 不难, 确 很 有 效 果, 何 乐 而 不 为 呢 ? 只 要 在 条 目 输 出时, 象 下 面 的 样 子
加 上 点 内 容, 想 要 的 效 果 就 有 了:
< a ... onmouseover="this.style.color=COLOR1"
onmouseout="this.style.color=COLOR2" ... >
---- 再 有 一 点, 在列 表
中, 我 们 使 用 的 是
|