BOM之location 對象
-
- 8.2 location 對象
-
- 8.2.1 查詢字元串參數
- 8.2.2 位置操作
- 8.3 navigator 對象
-
- 8.3.1 檢測插件
- 8.3.2 注冊處理程式
- 8.4 screen 對象
- 8.5 history 對象
8.2 location 對象
location 是最有用的 BOM 對象之一,它提供了與目前視窗中加載的文檔有關的資訊,還提供了一些導航功能。事實上, location 對象是很特别的一個對象,因為它既是 window 對象的屬性,也是document 對象的屬性;換句話說,window.location 和 document.location 引用的是同一個對象。location 對象的用處不隻表現在它儲存着目前文檔的資訊,還表現在它将 URL 解析為獨立的片段,讓開發人員可以通過不同的屬性通路這些片段。
8.2.1 查詢字元串參數
盡管 location.search 傳回從問号到 URL 末尾的所有内容,但卻沒有辦法逐個
通路其中的每個查詢字元串參數。為此,可以像下面這樣建立一個函數,用以解析查詢字元串,然後返
回包含所有參數的一個對象:
function getQueryStringArgs(){
//取得查詢字元串并去掉開頭的問号
var qs = (location.search.length > 0 ? location.search.substring(1) : ""),
//儲存資料的對象
args = {},
//取得每一項
items = qs.length ? qs.split("&") : [],
item = null,
name = null,
value = null,
//在 for 循環中使用
i = 0,
len = items.length;
//逐個将每一項添加到 args 對象中
for (i=0; i < len; i++){
item = items[i].split("=");
name = decodeURIComponent(item[0]);
value = decodeURIComponent(item[1]);
if (name.length) {
args[name] = value;
}
}
return args;
}
//假設查詢字元串是?q=javascript&num=10
var args = getQueryStringArgs();
alert(args["q"]); //"javascript"
alert(args["num"]); //"10"
8.2.2 位置操作
使用 location 對象可以通過很多方式來改變浏覽器的位置。首先,也是最常用的方式,就是使用assign()方法并為其傳遞一個 URL,如下所示。
location.assign("http://www.wrox.com");
下列兩行代碼與
顯式調用 assign()方法的效果完全一樣。
window.location = "http://www.wrox.com";
location.href = "http://www.wrox.com";
在這些改變浏覽器位置的方法中,最常用的是設定 location.href 屬性。
另外,修改location 對象的其他屬性也可以改變目前加載的頁面。下面的例子展示了通過将hash、search、 hostname、 pathname 和 port 屬性設定為新值來改變 URL。
//假設初始 URL 為 http://www.wrox.com/WileyCDA/
//将 URL 修改為"http://www.wrox.com/WileyCDA/#section1"
location.hash = "#section1";
//将 URL 修改為"http://www.wrox.com/WileyCDA/?q=javascript"
location.search = "?q=javascript";
//将 URL 修改為"http://www.yahoo.com/WileyCDA/"
location.hostname = "www.yahoo.com";
//将 URL 修改為"http://www.yahoo.com/mydir/"
location.pathname = "mydir";
//将 URL 修改為"http://www.yahoo.com:8080/WileyCDA/"
location.port = 8080;
每次修改 location 的屬性(hash 除外),頁面都會以新 URL 重新加載。
當通過上述任何一種方式修改 URL 之後,浏覽器的曆史記錄中就會生成一條新記錄,是以使用者通過單擊“後退”按鈕都會導航到前一個頁面。要禁用這種行為,可以使用 **replace()**方法。這個方法隻接受一個參數,即要導航到的 URL;結果雖然會導緻浏覽器位置改變,但不會在曆史記錄中生成新記錄。在調用 replace()方法之後,使用者不能回到前一個頁面。
<!DOCTYPE html>
<html>
<head>
<title>You won't be able to get back here</title>
</head>
<body>
<p>Enjoy this page for a second, because you won't be coming back here.</p>
<script type="text/javascript">
setTimeout(function () {
location.replace("http://www.wrox.com/");
}, 1000);
</script>
</body>
</html>
與位置有關的最後一個方法是 reload(),作用是重新加載目前顯示的頁面。如果調用 reload()時不傳遞任何參數,頁面就會以最有效的方式重新加載。也就是說,如果頁面自上次請求以來并沒有改變過,頁面就會從浏覽器緩存中重新加載。如果要強制從伺服器重新加載,則需要像下面這樣為該方法傳遞參數 true。
location.reload(); //重新加載(有可能從緩存中加載)
location.reload(true); //重新加載(從伺服器重新加載)
位于 reload()調用之後的代碼可能會也可能不會執行,這要取決于網絡延遲或系統資源等因素。最好将 reload()放在代碼的最後一行。
8.3 navigator 對象
最早由 Netscape Navigator 2.0 引入的 navigator 對象,現在已經成為識别用戶端浏覽器的事實标準。
8.3.1 檢測插件
對于非 IE 浏覽器,可以使用plugins 數組來達到這個目的。該數組中的每一項都包含下列屬性。
name:插件的名字。
description:插件的描述。
filename:插件的檔案名。
length:插件所處理的 MIME 類型數量。
一般來說, name 屬性中會包含檢測插件必需的所有資訊,但有時候也不完全如此。在檢測插件時,需要像下面這樣循環疊代每個插件并将插件的 name 與給定的名字進行比較。
//檢測插件(在 IE 中無效)
function hasPlugin(name){
name = name.toLowerCase();
for (var i=0; i < navigator.plugins.length; i++){
if (navigator. plugins [i].name.toLowerCase().indexOf(name) > -1){
return true;
}
}
return false;
}
//檢測 Flash
alert(hasPlugin("Flash"));
//檢測 QuickTime
alert(hasPlugin("QuickTime"));
檢測 IE 中的插件比較麻煩,因為 IE 不支援 Netscape 式的插件。在 IE 中檢測插件的唯一方式就是使用專有的 ActiveXObject 類型,并嘗試建立一個特定插件的執行個體。 IE 是以 COM 對象的方式實作插件的,而 COM 對象使用唯一辨別符來辨別。是以,要想檢查特定的插件,就必須知道其 COM 辨別符。例如, Flash 的辨別符是 ShockwaveFlash.ShockwaveFlash。知道唯一辨別符之後,就可以編寫類似下面的函數來檢測 IE 中是否安裝相應插件了。
//檢測 IE 中的插件
function hasIEPlugin(name){
try {
new ActiveXObject(name);
return true;
} catch (ex){
return false;
}
}
//檢測 Flash
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash"));
//檢測 QuickTime
alert(hasIEPlugin("QuickTime.QuickTime"));
//檢測所有浏覽器中的 Flash
function hasFlash(){
var result = hasPlugin("Flash");
if (!result){
result = hasIEPlugin("ShockwaveFlash.ShockwaveFlash");
}
return result;
}
//檢測所有浏覽器中的 QuickTime
function hasQuickTime(){
var result = hasPlugin("QuickTime");
if (!result){
result = hasIEPlugin("QuickTime.QuickTime");
}
return result;
}
//檢測 Flash
alert(hasFlash());
//檢測 QuickTime
alert(hasQuickTime());
8.3.2 注冊處理程式
Firefox 2 為 navigator 對象新增了 registerContentHandler()和 registerProtocolHandler()方法(這兩個方法是在 HTML5 中定義的)其中, registerContentHandler()方法接收三個參數:要處理的 MIME 類型、可以處理該 MIME類型的頁面的 URL 以及應用程式的名稱。舉個例子,要将一個站點注冊為處理 RSS 源的處理程式,可以使用如下代碼。
navigator.registerContentHandler("application/rss+xml",
"http://www.somereader.com?feed=%s", "Some Reader");
Firefox 4 及之前版本隻允許在 registerContentHandler()方法中使用三個
MIME 類型: application/rss+xml、 application/atom+xml 和 application/
vnd.mozilla.maybe. feed。這三個 MIME 類型的作用都一樣,即為 RSS 或 ATOM
新聞源(feed)注冊處理程式。
8.4 screen 對象
screen 對象基本上隻用來表明用戶端的能力,其中包括浏覽器視窗外部的顯示器的資訊,如像素寬度和高度等。
window.resizeTo(screen.availWidth, screen.availHeight);
8.5 history 對象
history 對象儲存着使用者上網的曆史記錄,是 window對象的屬性,是以每個浏覽器視窗、每個标簽頁乃至每個架構,都有自己的 history 對象與特定的window 對象關聯。出于安全方面的考慮,開發人員無法得知使用者浏覽過的 URL。借由使用者通路過的頁面清單,同樣可以在不知道實際 URL 的情況下實作後退和前進。使用 **go()**方法可以在使用者的曆史記錄中任意跳轉,可以向後也可以向前。負數表示向後跳轉(類似于單擊浏覽器的“後退”按鈕),正數表示向前跳轉
//後退一頁
history.go(-1);
//前進一頁
history.go(1);
//前進兩頁
history.go(2);
也可以給 go()方法傳遞一個字元串參數,此時浏覽器會跳轉到曆史記錄中包含該字元串的第一個位置——可能後退,也可能前進,具體要看哪個位置最近。如果曆史記錄中不包含該字元串,那麼這個方法什麼也不做
//跳轉到最近的 wrox.com 頁面
history.go("wrox.com");
//跳轉到最近的 nczonline.net 頁面
history.go("nczonline.net");
另外,還可以使用兩個簡寫方法 back()和 forward()來代替 go()。顧名思義,這兩個方法可以模仿浏覽器的“後退”和“前進”按鈕。
//後退一頁
history.back();
//前進一頁
history.forward();
除了上述幾個方法外, history 對象還有一個 length 屬性,儲存着曆史記錄的數量。這個數量包括所有曆史記錄,即所有向後和向前的記錄。對于加載到視窗、标簽頁或架構中的第一個頁面而言,history.length 等于 0。通過像下面這樣測試該屬性的值,可以确定使用者是否一開始就打開了你的頁面。
if (history.length == 0){
//這應該是使用者打開視窗後的第一個頁面
}
當頁面的 URL 改變時,就會生成一條曆史記錄。在 IE8 及更高版本、 Opera、
Firefox、 Safari 3 及更高版本以及 Chrome 中,這裡所說的改變包括 URL 中hash 的變化(是以,設定 location.hash 會在這些浏覽器中生成一條新的曆史記錄)。