第 三 部 分: 框

也 许 你 会 问,JavaScript 和 框 之 间 究 竟 有 什 么 关 系 呢? 首 先 让 我 来 解 释 一 下 究 竟 什 么 是 框, 它 们 能 用 来 作 什 么? 然 后 我 们 来 看 看 如 何 在 框 中 应 用 JavaScript。
浏 览 器 显 示 的 窗 口 可 以 被 分 为 几 个 框。 这 意 味 着, 一 个 框 就 是 浏 览 器 窗 口 中 的 一 个 方 形 区 域。 每 一 个 框 都 显 示 了 一 个 文 本 ( 大 多 是 HTML 文 本), 比 如 你 可 以 生 成 一 个 有 两 个 框 的 web 页, 第 一 个 框 用 来 显 示 Netscape 公 司 的 主 页, 第 二 个 框 用 来 显 示 Microsoft 公 司 的 主 页。
虽 然 生 成 一 个 框 是 基 本 的 HTML 应 用, 但 我 会 描 述 一 下 如 何 生 成 它。 要 生 成 框, 你 需 要 两 个 标 记 符: <frameset> and <frame>. 一 个 有 两 个 框 的 HTML 页 看 起 来 象 这 样:


<html>
<frameset rows="50%,50%"> 
  <frame src="page1.htm" name="frame1"> 
  <frame src="page2.htm" name="frame2"> 
</frameset> 
</html>

这 会 生 成 两 个 框。 你 能 看 到 我 们 在 <frameset> 中 用 了 它 的 属 性 rows 。 这 意 味 着 两 个 框 是 一 个 在 一 个 上 面。 上 面 的 框 加 载 了 page1.htmHTML 页, 下 面 的 框 显 示 了 page2.htm HTML 页。 如 果 你 按 下 了 按 钮, 你 就 可 以 看 到 这 个 HTML 页 了:

如 果 你 要 让 框 并 排 排 列 而 不 是 上 下 排 列, 那 你 可 以 在 <frameset> 中 用 cols 属 性 代 替 rows 属 性。 源 代 码 中 "50%,50%" 的 部 分 指 明 了 两 个 窗 口 分 别 有 多 大。 如 果 你 不 愿 意 计 算 剩 下 的 部 分 有 多 大 时, 你 也 能 只 写 "50%,*"。 你 也 可 以 直 接 用 象 素 来 指 定 大 小, 而 不 使 用 百 分 号 % 。
每 一 个 框 都 可 以 用 <frame> 的 name 属 性 来 指 定 一 个 名 字。 这 能 帮 助 我 们 通 过 使 用 JavaScript 来 存 取 不 同 的 框。

你 可 以 使 用 嵌 套 的 <frameset> 标 记 符。 下 面 这 个 例 子 是 从 Netscape 公 司 的 文 档 中 借 用 来 的( 我 只 改 动 了 一 点):


<frameset cols="50%,50%"> 
  <frameset rows="50%,50%"> 
    <frame src="cell.htm"> 
    <frame src="cell.htm"> 
  </frameset> 
  <frameset rows="33%,33%,33%"> 
    <frame src="cell.htm"> 
    <frame src="cell.htm"> 
    <frame src="cell.htm"> 
  </frameset> 
</frameset> 

看 一 看 这 个 例 子:

你 能 通 过 使 用 <frameset> 的 border 特 性 来 设 置 边 界 的 粗 细。 border=0 意 味 着 你 不 想 要 边 界。( 不 能 在 Netscape 2.x 中 使 用)。

框 和 Javascript

现 在 我 们 来 看 看 JavaScript 如 何 在 浏 览 器 窗 口 中 如 何 使 用 框。 让 我 们 先 来 看 看 本 页 上 面 的 第 一 个 例 子。
我 们 已 经 知 道 JavaScript 管 理 web 页 上 元 素 的 结 构。 这 对 于 框 也 是 同 样 的。

 

结 构 的 顶 上 是 浏 览 器 窗 口。 这 个 窗 口 被 分 成 两 个 框。 这 个 窗 口 在 这 个 结 构 中 是“ 父 结 构”, 框 是“ 子 结 构”。 我 们 把 两 个 框 分 别 命 名 为 frame1 和 frame2。 通 过 这 两 个 名 字 我 们 能 在 这 两 个 框 间 交 换 信 息。
通 过 使 用 Javascript 语 言 可 以 解 决 下 面 的 问 题: 用 户 单 击 在 第 一 个 框 中 的 一 个 连 接, 但 载 入 的 页 却 显 示 在 第 二 个 框 中。 这 只 要 应 用 在 菜 单 框 ( 或 引 导 框 )中: 一 个 框 中 的 内 容 始 终 不 变, 而 通 过 不 同 的 连 接 在 另 一 个 框 中 展 示 不 同 的 内 容。
我 们 来 看 看 三 种 不 同 的 情 况:

从 窗 口 的 观 点 来 看 frame1 框 和 frame2 框。 你 可 以 从 上 面 的 图 中 看 到 从“ 父 窗 口” 到 每 一 个 框 有 一 个 直 接 的 连 接。 所 以 如 果 你 在“ 父 窗 口”- 你 用 来 生 成 框 的 web 页= 指 定 了 的 话, 你 可 以 通 过 直 接 使 用 框 的 名 字 来 使 用 它。 比 如 你 可 以 这 样 写:


frame2.document.write("A message from the parent window.");

有 时 候 你 会 想 从 框 内 使 用“ 父 窗 口”。 这 主 要 用 在 你 想 不 再 使 用 框 的 时 候。 这 也 就 是 说 在 你 要 载 入 一 个 新 的 不 含 有 框 的 页 时。 在 这 儿 我 们 姑 且 认 为 是 载 入“ 父 窗 口” 的 内 容。 我 们 可 以 在“ 子 窗 口”中 使 用 parent 来 调 用“ 父 窗 口”。 为 了 载 入 一 个 新 的 页 我 们 要 通 过 使 用 location.href 来 载 入 一 个 新 的 URL。 为 了 移 走 框 我 们 还 必 须 使 用“ 父 窗 口” 的 位 置 对 象。 在 各 个 框 中 要 载 入 新 的 页 就 要 使 用 不 同 的 位 置 对 象。 我 们 能 通 过 使 用 下 面 的 命 令 在“ 父 窗 口” 中 载 入 一 个 新 的 页:


parent.location.href= "http://...";

你 经 常 会 碰 上 这 样 的 问 题: 如 何 在 一 个“ 子 窗 口” 中 访 问 另 一 个“ 子 窗 口” 呢, 如 何 从 第 一 个 框 向 第 二 个 框 内 写 一 些 东 西 呢- 这 也 就 是 说 我 们 究 竟 在 page1.htm 要 用 什 么 样 的 命 令 呢 ? 在 上 面 的 图 中 你 可 以 看 到 在 两 个 框 间 没 有 直 接 的 连 接。 这 也 就 是 说, 我 们 不 能 直 接 在 frame1 中 直 接 调 用 frame2, 因 为 在 frame1 的 观 点 来 看, 它 并 不 知 道 存 在 另 一 个 框, 它 只 知 道 parent 是“ 父 窗 口” 的 名 字。 而“ 父 窗 口” 却 知 道 同 时 存 在 两 个 框。 所 以 我 们 必 须 使 用 下 面 的 命 令 来 访 问 第 二 个 框 的 文 本 对 象:


parent.frame2.document.write("Hi, this is frame1 calling.");

引 导 框

让 我 们 来 看 看 什 么 是 引 导 框: 在 一 个 框 中 有 一 些 连 接, 当 你 单 击 连 接 时, 载 入 的 web 页 并 不 在 这 个 框 中 出 现, 它 出 现 在 第 二 个 框 中。

这 是 一 个 例 子:

首 先 我 们 使 用 Javascript 来 生 成 这 些 框。 这 有 点 象 这 部 分 的 第 一 个 例 子:

frames3.htm


<html>
<frameset rows="80%,20%"> 
  <frame src="start.htm" name="main"> 
  <frame src="menu.htm" name="menu"> 
</frameset> 
</html>

这 个 start.htm 页 是 一 开 始 展 现 在 main 框 中 的 页, 对 这 个 页 没 有 什 么 特 殊 的 要 求。
下 面 这 个 页 是 载 入 在 框 menu 中 的 页:

menu.htm


<html>
<head>
<script language="JavaScript">
<!-- hide

function load(url) {
  parent.main.location.href= url;
}

// -->
</script>
</head>
<body>

<a href="javascript:load('first.htm')">first</a>
<a href="second.htm" target="main">second</a>
<a href="third.htm" target="_top">third</a>

</body>
</html>

这 儿 你 可 以 看 到 main 框 中 载 入 页 的 不 同 方 法。 第 一 个 连 接 使 用 函 数 load()。 看 一 看 这 个 函 数 是 如 何 被 调 用 的:


<a href="javascript:load('first.htm')">first</a>

你 可 以 看 到 我 们 让 浏 览 器 运 行 JavaScript 代 码, 而 不 是 直 接 载 入 一 个 页 - 我 们 只 需 要 使 用 href 的 javascript: 特 性。 括 号 中 写 的 是 'first.htm'。 这 个 字 符 串 会 传 递 到 函 数 load() 中。 函 数 load() 是 这 样 定 义 的:


function load(url) {
  parent.main.location.href= url;
}

这 儿 你 可 以 看 到 我 们 在 括 号 中 写 的 是 url。 这 意 味 着 我 们 把 字 符 串 'first1.htm' 存 储 在 变 量 url 中。 现 在 我 们 可 以 在 函 数 load() 中 使 用 这 个 变 量。 在 以 后 我 们 能 够 看 到 关 于 变 量 的 更 多 的 例 子。
第 二 个 连 接 使 用 了 target 特 性。 准 确 的 说 这 并 不 是 JavaScript。 这 是 HTML 特 性。 你 看 我 们 只 需 要 指 定 框 的 名 字。 请 记 住 我 们 不 需 要 在 框 的 名 字 前 放 上 parent。 这 也 许 有 一 点 令 人 迷 惑。 这 样 作 的 原 因 只 是 因 为 target 是 HTML 而 不 是 JavaScript。
第 三 个 连 接 显 示 了 如 何 通 过 使 用 target 特 性 来 移 走 框。
如 果 你 想 通 过 使 用 函 数 load() 来 移 走 框, 你 只 需 在 函 数 中 加 入 parent.location.href= url。

你 准 备 选 哪 一 种 方 法 呢? 这 要 由 你 自 己 来 决 定 了。 target 特 性 十 分 简 单。 如 果 你 只 是 想 在 另 一 个 框 中 载 入 一 个 页 的 话 就 用 它 吧。 JavaScript 代 码 ( 就 象 第 一 个 连 接 ) 经 常 用 在 当 你 单 击 一 个 连 接 后 会 产 生 一 系 列 的 反 应 时。 比 如 同 时 在 两 个 框 中 载 入 两 个 页。 虽 然 你 也 可 以 通 过 使 用 target 来 解 决 这 个 问 题, 担 使 用 JavaScript 函 数 更 直 接。 让 我 们 假 定 你 有 三 个 框, 分 别 是 frame1,frame2 和 frame3。 用 户 单 击 了 frame1 中 的 一 个 连 接 后, 你 想 在 另 两 个 不 同 的 框 中 载 入 两 个 不 同 的 页。 你 可 以 使 用 这 样 一 个 函 数:


function loadtwo() {
  parent.frame1.location.href= "first.htm";
  parent.frame2.location.href= "second.htm";
}

如 果 你 想 使 这 个 函 数 更 通 用, 你 可 以 在 这 儿 使 用 变 量, 就 象 下 面 这 样:


function loadtwo(url1, url2) {
  parent.frame1.location.href= url1;
  parent.frame2.location.href= url2;
}

现 在 你 能 够 这 样 调 用 这 个 函 数 loadtwo("first.htm", "second.htm") 或 者 loadtwo("third.htm", "forth.htm")。 变 量 可 以 使 你 的 函 数 通 用 性 更 好。 你 可 以 在 以 后 反 复 使 用 它。