使用 Firefox 1.5 缓存
Firefox 1.5 使用内存缓存来存储整个网页,包括其 JavaScript 状态,用于单个浏览器会话。在已访问页面之间前后切换无需页面加载,并且 JavaScript 状态将保留。此功能,有些人将其称为 bfcache(代表“Back-Forward Cache”),使页面导航非常快速。此缓存状态将保留,直到用户关闭浏览器。
在某些情况下,Firefox 不会缓存页面。以下是一些导致页面未被缓存的常见编程原因
- 页面使用
unload
或beforeunload
处理程序; - 页面设置“cache-control: no-store”。
- 站点为 HTTPS 且页面至少设置以下一项
- "Cache-Control: no-cache"
- "Pragma: no-cache"
- 以及“Expires: 0”或“Expires”具有相对于“Date”标头值而言的过去日期值(除非还指定了“Cache-Control: max-age=”);
- 用户离开页面时页面未完全加载或由于其他原因(例如
XMLHttpRequest
)存在未完成的网络请求; - 页面具有正在运行的 IndexedDB 事务;
- 顶级页面包含框架(例如
<iframe>
),由于此处列出的任何原因而无法缓存; - 页面位于框架中,用户在该框架内加载新页面(在这种情况下,当用户离开页面时,最后加载到框架中的内容将被缓存)。
此新的缓存功能会更改页面加载行为,Web 作者可能希望
- 知道已导航到页面(当它从用户的缓存中加载时)
- 定义用户离开页面时的页面行为(同时仍允许缓存页面)
两个新的浏览器事件使 Web 作者能够同时执行这两项操作。
新的浏览器事件
如果您使用这些新事件,您的页面将继续在其他浏览器中正确显示(我们已测试了早期版本的 Firefox、Internet Explorer、Opera 和 Safari),并在 Firefox 1.5 中加载时使用此新的缓存功能。
注意:截至 2009 年 10 月,Safari 的开发版本添加了对这些新事件的支持(请参阅 WebKit 错误)。
网页的标准行为是
- 用户导航到页面。
- 页面加载时,内联脚本运行。
- 页面加载完成后,
onload
处理程序将触发。
某些页面包含第四个步骤。如果页面使用 unload
或 beforeunload
处理程序,则当用户离开页面时,它将触发。如果存在 unload
处理程序,则页面将不会被缓存。
当用户导航到缓存的页面时,内联脚本和 onload
处理程序不会运行(步骤 2 和 3),因为在大多数情况下,这些脚本的效果已保留。
如果页面包含在加载期间触发的脚本或其他行为,您希望每次用户导航到页面时都继续执行,或者如果您想知道用户何时导航到缓存的页面,请使用新的 pageshow
事件。
如果您有一些在用户离开页面时触发的行为,但您想利用此新缓存功能,因此不想使用 unload 处理程序,请使用新的 pagehide
事件。
pageshow 事件
此事件的工作方式与 load
事件相同,除了它每次加载页面时都会触发(而 load
事件在 Firefox 1.5 中从缓存加载页面时不会触发)。页面第一次加载时,pageshow
事件会在 load
事件触发后立即触发。pageshow
事件使用一个名为 persisted
的布尔属性,该属性在初始加载时设置为 false
。如果它不是初始加载,则将其设置为 true
(换句话说,当页面被缓存时,它将设置为 true)。
将您希望每次加载页面时运行的任何 JavaScript 设置为在 pageshow
事件触发时运行。
如果您在 pageshow
事件中调用 JavaScript 函数,您可以确保这些函数在除 Firefox 1.5 之外的浏览器中加载页面时被调用,方法是在 load
事件中调用 pageshow
事件,如本文后面的示例所示。
pagehide 事件
如果您想定义用户离开页面时发生的行为,但不想使用 unload
事件(这会导致页面不被缓存),则可以使用新的 pagehide
事件。与 pageshow
一样,pagehide
事件使用一个名为 persisted
的布尔属性。如果页面未被浏览器缓存,则此属性设置为 false
;如果页面被浏览器缓存,则设置为 true
。当此属性设置为 false
时,如果存在 unload
处理程序,则它将在 pagehide
事件之后立即触发。
Firefox 1.5 尝试以与页面最初加载时相同的顺序模拟加载事件。框架的处理方式与顶级文档相同。如果页面包含框架,则当加载缓存的页面时
- 每个框架的
pageshow
事件将在主文档中的pageshow
事件触发之前触发。 - 当用户离开缓存的页面时,每个框架的
pagehide
事件将在主文档中的pagehide
事件触发之前触发。 - 对于在单个框架内发生的导航,事件仅在受影响的框架中触发。
示例代码
以下示例说明了一个同时使用 load
和 pageshow
事件的页面。此示例页面的行为如下
- 在除 Firefox 1.5 之外的浏览器中,每次加载页面时都会发生以下情况:
load
事件触发onLoad
函数,该函数调用onPageShow
函数(以及其他函数)。 - 在 Firefox 1.5 中,页面第一次加载时,
load
事件的工作方式与其他浏览器相同。此外,pageshow
事件会触发,并且由于persisted
设置为false
,因此不会发生其他操作。 - 在 Firefox 1.5 中,当页面从缓存中加载时,只有
pageshow
事件会触发。由于persisted
设置为true
,因此只会触发onPageShow
函数中的 JavaScript 操作。
在此示例中
- 每次加载页面时,页面都会计算并显示当前日期和时间。此计算包括秒和毫秒,因此您可以轻松测试功能。
- 第一次加载页面时,光标将置于表单的“名称”字段中。在 Firefox 1.5 中,当用户返回页面时,光标将保留在用户离开页面时的位置。在其他浏览器中,光标将移回“名称”字段。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Order query Firefox 1.5 Example</title>
<style type="text/css">
body,
p {
font-family: Verdana, sans-serif;
font-size: 12px;
}
</style>
<script>
function onLoad() {
loadOnlyFirst();
onPageShow();
}
function onPageShow() {
//calculate current time
var currentTime = new Date();
var year = currentTime.getFullYear();
var month = currentTime.getMonth() + 1;
var day = currentTime.getDate();
var hour = currentTime.getHours();
var min = currentTime.getMinutes();
var sec = currentTime.getSeconds();
var mil = currentTime.getMilliseconds();
var displayTime =
month +
"/" +
day +
"/" +
year +
" " +
hour +
":" +
min +
":" +
sec +
":" +
mil;
document.getElementById("timefield").value = displayTime;
}
function loadOnlyFirst() {
document.zipForm.name.focus();
}
</script>
</head>
<body onload="onLoad();" onpageshow="if (event.persisted) onPageShow();">
<h2>Order query</h2>
<form
name="zipForm"
action="http://www.example.com/formresult.html"
method="get">
<label for="timefield">Date and time:</label>
<input type="text" id="timefield" /><br />
<label for="name">Name:</label>
<input type="text" id="name" /><br />
<label for="address">Email address:</label>
<input type="text" id="address" /><br />
<label for="order">Order number:</label>
<input type="text" id="order" /><br />
<input type="submit" name="submit" value="Submit Query" />
</form>
</body>
</html>
相反,如果上述页面未侦听 pageshow
事件,并将所有计算作为 load
事件的一部分进行处理(而是按照下面的示例代码片段中所示进行编码),则当用户离开页面时,光标位置和日期/时间都将在 Firefox 1.5 中被缓存。当用户返回页面时,将显示缓存的日期/时间。
<script>
function onLoad() {
loadOnlyFirst();
//calculate current time
var currentTime= new Date();
var year = currentTime.getFullYear();
var month = currentTime.getMonth()+1;
var day = currentTime.getDate();
var hour=currentTime.getHours();
var min=currentTime.getMinutes();
var sec=currentTime.getSeconds();
var mil=currentTime.getMilliseconds();
var displayTime = (month + "/" + day + "/" + year + " " +
hour + ":" + min + ":" + sec + ":" + mil);
document.getElementById("timefield").value=displayTime;
}
function loadOnlyFirst() {
document.zipForm.name.focus();
}
</script>
</head>
<body onload="onLoad();">
开发 Firefox 扩展
Firefox 1.5 扩展 需要允许此缓存功能。如果您正在开发希望与 1.5 和早期版本兼容的 Firefox 扩展,请确保它侦听 load
事件以获取可缓存的触发器,并侦听 pageshow
事件以获取不应缓存的触发器。
例如,Firefox 的 Google 工具栏应侦听 load
事件以获取自动链接功能,并侦听 pageshow
事件以获取 PageRank 功能,以便与 1.5 和早期版本兼容。