JavaScript 基礎入門07
BOM
當
js的運行環境為瀏覽器時,學習js應該將其分成三個部分:ECMAScript核心語法、BOM、DOM。
BOM我們可以將其稱之為瀏覽器對象模型,主要描述了與瀏覽器進行交互的方法和接口。
IE 3.0 和 Netscape Navigator 3.0 提供了一種特性 - BOM(瀏覽器對象模型),可以對瀏覽器窗口進行訪問和操作。使用 BOM,開發者可以移動窗口、改變狀態欄中的文本以及執行其他與頁面內容不直接相關的動作。使 BOM 獨樹一幟且又常常令人懷疑的地方在於,它只是 JavaScript 的一個部分,沒有任何相關的標准。
BOM 主要處理瀏覽器窗口和框架,不過通常瀏覽器特定的 JavaScript 擴展都被看做 BOM 的一部分。這些擴展包括:
- 彈出新的瀏覽器窗口
- 移動、關閉瀏覽器窗口以及調整窗口大小
- 提供 Web 瀏覽器詳細信息的定位對象
- 提供用戶屏幕分辨率詳細信息的屏幕對象
- 對 cookie 的支持
- IE 擴展了 BOM,加入了 ActiveXObject 類,可以通過 JavaScript 實例化 ActiveX 對象
由於沒有相關的 BOM 標准,每種瀏覽器都有自己的 BOM 實現。有一些事實上的標准,如具有一個窗口對象和一個導航對象,不過每種瀏覽器可以為這些對象或其他對象定義自己的屬性和方法。
下面是一些BOM當中包含的對象。
- Window對象
- Navigator對象
- Screen對象
- History對象
- Location對象
window對象
瀏覽器里面,window對象(注意,w為小寫)指當前的瀏覽器窗口。它也是當前頁面的頂層對象,即最高一層的對象,所有其他對象都是它的下屬。一個變量如果未聲明,那么默認就是頂層對象的屬性。
例如:
a = 1;
window.a // 1
上面代碼中,a是一個沒有聲明就直接賦值的變量,它自動成為頂層對象的屬性。
window有自己的實體含義,其實不適合當作最高一層的頂層對象,這是一個語言的設計失誤。最早,設計這門語言的時候,原始設想是語言內置的對象越少越好,這樣可以提高瀏覽器的性能。因此,語言設計者 Brendan Eich 就把window對象當作頂層對象,所有未聲明就賦值的變量都自動變成window對象的屬性。這種設計使得編譯階段無法檢測出未聲明變量,但到了今天已經沒有辦法糾正了。
window對象的屬性
1、window.name
window.name屬性是一個字符串,表示當前瀏覽器窗口的名字。窗口不一定需要名字,這個屬性主要配合超鏈接和表單的target屬性使用。
window.name = 'Hello World!';
console.log(window.name)
// "Hello World!"
該屬性只能保存字符串,如果寫入的值不是字符串,會自動轉成字符串。各個瀏覽器對這個值的儲存容量有所不同,但是一般來說,可以高達幾MB。
只要瀏覽器窗口不關閉,這個屬性是不會消失的。舉例來說,訪問a.com時,該頁面的腳本設置了window.name,接下來在同一個窗口里面載入了b.com,新頁面的腳本可以讀到上一個網頁設置的window.name。頁面刷新也是這種情況。一旦瀏覽器窗口關閉后,該屬性保存的值就會消失,因為這時窗口已經不存在了。
2、window.closed,window.opener
window.closed屬性返回一個布爾值,表示窗口是否關閉。
window.closed // false
上面代碼檢查當前窗口是否關閉。這種檢查意義不大,因為只要能運行代碼,當前窗口肯定沒有關閉。這個屬性一般用來檢查,使用腳本打開的新窗口是否關閉。
var popup = window.open();
if ((popup !== null) && !popup.closed) {
// 窗口仍然打開着
}
我們可以通過window.open方法打開一個新的網頁。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn">點擊打開</button>
</body>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
window.open('https://www.baidu.com')
}
</script>
</html>
window.opener屬性是一個可讀可寫的屬性,可返回對創建該窗口的 Window 對象的引用。
當使用window.open()打開一個窗口,您可以使用此屬性返回來自目標窗口源(父)窗口的詳細信息。
window.opener.close()將關閉源(父)窗口。
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn">點擊打開</button>
</body>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
var a = window.open('','','width=200,height=200');
console.log(a.opener.document.write('hello,world'))
}
</script>
</html>
也可以通過window.opener.close()關閉父源窗口。
a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn">點擊打開</button>
</body>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
var a = window.open('b.html','','width=200,height=200');
console.log(a.opener.document.write('hello,world'))
}
</script>
</html>
b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn">點擊</button>
</body>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
window.opener.close();
}
</script>
</html>
如果當前窗口沒有父源窗口,則返回
null。
如果在兩個窗口之間不需要通訊,那么建議將window.opener屬性設置為null,這樣能夠減少安全隱患。
zvar newWin = window.open('example.html', 'newWindow', 'height=400,width=400');
newWin.opener = null;
一旦屬性設置為null,那么兩個窗口之間將不在能通信。
3、window.self 和 window.window
window.self和window.window屬性都指向窗口本身。這兩個屬性只讀。
window.self === window // true
window.window === window // true
4、位置大小屬性
window.screenX ,window.screenY
window.screenX和window.screenY屬性,返回瀏覽器窗口左上角相對於當前屏幕左上角的水平距離和垂直距離(單位像素)。這兩個屬性只讀。
window.innerHeight,window.innerWidth
window.innerHeight和window.innerWidth屬性,返回網頁在當前窗口中可見部分的高度和寬度,即“視口”(viewport)的大小(單位像素)。這兩個屬性只讀。
用戶放大網頁的時候(比如將網頁從100%的大小放大為200%),這兩個屬性會變小。因為這時網頁的像素大小不變(比如寬度還是960像素),只是每個像素占據的屏幕空間變大了,因為可見部分(視口)就變小了。
注意,這兩個屬性值包括滾動條的高度和寬度。
window.outerHeight,window.outerWidth
window.outerHeight和window.outerWidth屬性返回瀏覽器窗口的高度和寬度,包括瀏覽器菜單和邊框(單位像素)。這兩個屬性只讀。
window.scrollX,window.scrollY
window.scrollX屬性返回頁面的水平滾動距離,window.scrollY屬性返回頁面的垂直滾動距離,單位都為像素。這兩個屬性只讀。
注意,這兩個屬性的返回值不是整數,而是雙精度浮點數。如果頁面沒有滾動,它們的值就是0。
舉例來說,如果用戶向下拉動了垂直滾動條75像素,那么window.scrollY就是75左右。用戶水平向右拉動水平滾動條200像素,window.scrollX就是200左右。
if (window.scrollY < 75) {
window.scroll(0, 75);
}
上面代碼中,如果頁面向下滾動的距離小於75像素,那么頁面向下滾動75像素。
window.pageXOffset,window.pageYOffset
window.pageXOffset屬性和window.pageYOffset屬性,是window.scrollX和window.scrollY別名。
5、組建屬性
組件屬性返回瀏覽器的組件對象。這樣的屬性有下面幾個。
window.locationbar:地址欄對象window.menubar:菜單欄對象window.scrollbars:窗口的滾動條對象window.toolbar:工具欄對象window.statusbar:狀態欄對象window.personalbar:用戶安裝的個人工具欄對象
這些對象的visible屬性是一個布爾值,表示這些組件是否可見。這些屬性只讀。
window.locationbar.visible
window.menubar.visible
window.scrollbars.visible
window.toolbar.visible
window.statusbar.visible
window.personalbar.visible
全局對象屬性
全局對象屬性指向一些瀏覽器原生的全局對象。
window.document:指向document對象window.location:指向Location對象window.navigator:指向Navigator對象window.history:指向History對象window.localStorage:指向本地儲存的 localStorage 數據window.sessionStorage:指向本地儲存的 sessionStorage 數據window.console:指向console對象,用於操作控制台window.screen:指向Screen對象,表示屏幕信息
window.isSecureContext
window.isSecureContext屬性返回一個布爾值,表示當前窗口是否處在加密環境。如果是 HTTPS 協議,就是true,否則就是false。
window對象的方法
window.alert(),window.prompt(),window.confirm()
window.alert()、window.prompt()、window.confirm()都是瀏覽器與用戶互動的全局方法。它們會彈出不同的對話框,要求用戶做出回應。注意,這三個方法彈出的對話框,都是瀏覽器統一規定的式樣,無法定制。
window.open(), window.close(),window.stop()
window.open方法用於新建另一個瀏覽器窗口,類似於瀏覽器菜單的新建窗口選項。它會返回新窗口的引用,如果無法新建窗口,則返回null。
var popup = window.open('somefile.html');
上面代碼會讓瀏覽器彈出一個新建窗口,網址是當前域名下的somefile.html
open方法一共可以接受三個參數。
window.open(url, windowName, [windowFeatures])
url:字符串,表示新窗口的網址。如果省略,默認網址就是about:blank。windowName:字符串,表示新窗口的名字。如果該名字的窗口已經存在,則占用該窗口,不再新建窗口。如果省略,就默認使用_blank,表示新建一個沒有名字的窗口。另外還有幾個預設值,_self表示當前窗口,_top表示頂層窗口,_parent表示上一層窗口。windowFeatures:字符串,內容為逗號分隔的鍵值對(詳見下文),表示新窗口的參數,比如有沒有提示欄、工具條等等。如果省略,則默認打開一個完整 UI 的新窗口。如果新建的是一個已經存在的窗口,則該參數不起作用,瀏覽器沿用以前窗口的參數。
例如:
var popup = window.open(
'somepage.html',
'DefinitionsWindows',
'height=200,width=200,location=no,status=yes,resizable=yes,scrollbars=yes'
);
上面代碼表示,打開的新窗口高度和寬度都為200像素,沒有地址欄,但有狀態欄和滾動條,允許用戶調整大小。
第三個參數可以設定如下屬性。
- left:新窗口距離屏幕最左邊的距離(單位像素)。注意,新窗口必須是可見的,不能設置在屏幕以外的位置。
- top:新窗口距離屏幕最頂部的距離(單位像素)。
- height:新窗口內容區域的高度(單位像素),不得小於100。
- width:新窗口內容區域的寬度(單位像素),不得小於100。
- outerHeight:整個瀏覽器窗口的高度(單位像素),不得小於100。
- outerWidth:整個瀏覽器窗口的寬度(單位像素),不得小於100。
- menubar:是否顯示菜單欄。
- toolbar:是否顯示工具欄。
- location:是否顯示地址欄。
- personalbar:是否顯示用戶自己安裝的工具欄。
- status:是否顯示狀態欄。
- dependent:是否依賴父窗口。如果依賴,那么父窗口最小化,該窗口也最小化;父窗口關閉,該窗口也關閉。
- minimizable:是否有最小化按鈕,前提是
dialog=yes。 - noopener:新窗口將與父窗口切斷聯系,即新窗口的
window.opener屬性返回null,父窗口的window.open()方法也返回null。 - resizable:新窗口是否可以調節大小。
- scrollbars:是否允許新窗口出現滾動條。
- dialog:新窗口標題欄是否出現最大化、最小化、恢復原始大小的控件。
- titlebar:新窗口是否顯示標題欄。
- alwaysRaised:是否顯示在所有窗口的頂部。
- alwaysLowered:是否顯示在父窗口的底下。
- close:新窗口是否顯示關閉按鈕。
對於那些可以打開和關閉的屬性,設為yes或1或不設任何值就表示打開,比如status=yes、status=1、status都會得到同樣的結果。如果想設為關閉,不用寫no,而是直接省略這個屬性即可。也就是說,如果在第三個參數中設置了一部分屬性,其他沒有被設置的yes/no屬性都會被設成no,只有titlebar和關閉按鈕除外(它們的值默認為yes)
上面這些屬性,屬性名與屬性值之間用等號連接,屬性與屬性之間用逗號分隔。
'height=200,width=200,location=no,status=yes,resizable=yes,scrollbars=yes'
另外,open()方法的第二個參數雖然可以指定已經存在的窗口,但是不等於可以任意控制其他窗口。為了防止被不相干的窗口控制,瀏覽器只有在兩個窗口同源,或者目標窗口被當前網頁打開的情況下,才允許open方法指向該窗口。
window.close方法用於關閉當前窗口,一般只用來關閉window.open方法新建的窗口。
popup.close()
window.stop()方法完全等同於單擊瀏覽器的停止按鈕,會停止加載圖像、視頻等正在或等待加載的對象。
window.stop()
window.moveTo(),window.moveBy()
window.moveTo()方法用於移動瀏覽器窗口到指定位置。它接受兩個參數,分別是窗口左上角距離屏幕左上角的水平距離和垂直距離,單位為像素。
window.moveTo(100, 200)
上面代碼將窗口移動到屏幕(100, 200)的位置。
window.moveBy方法將窗口移動到一個相對位置。它接受兩個參數,分布是窗口左上角向右移動的水平距離和向下移動的垂直距離,單位為像素。
window.moveBy(25, 50)
上面代碼將窗口向右移動25像素、向下移動50像素。
為了防止有人濫用這兩個方法,隨意移動用戶的窗口,目前只有一種情況,瀏覽器允許用腳本移動窗口:該窗口是用window.open方法新建的,並且它所在的 Tab 頁是當前窗口里面唯一的。除此以外的情況,使用上面兩個方法都是無效的。
window.resizeTo(),window.resizeBy()
window.resizeTo()方法用於縮放窗口到指定大小。
它接受兩個參數,第一個是縮放后的窗口寬度(outerWidth屬性,包含滾動條、標題欄等等),第二個是縮放后的窗口高度(outerHeight屬性)。
window.resizeTo(
window.screen.availWidth / 2,
window.screen.availHeight / 2
)
上面代碼將當前窗口縮放到,屏幕可用區域的一半寬度和高度。
window.resizeBy()方法用於縮放窗口。它與window.resizeTo()的區別是,它按照相對的量縮放,window.resizeTo()需要給出縮放后的絕對大小。
它接受兩個參數,第一個是水平縮放的量,第二個是垂直縮放的量,單位都是像素。
window.resizeBy(-200, -200)
上面的代碼將當前窗口的寬度和高度,都縮小200像素。
window.scrollTo(),window.scroll(),window.scrollBy()
window.scrollTo方法用於將文檔滾動到指定位置。它接受兩個參數,表示滾動后位於窗口左上角的頁面坐標。
window.scrollTo(x-coord, y-coord)
它也可以接受一個配置對象作為參數。
window.scrollTo(options)
配置對象options有三個屬性。
top:滾動后頁面左上角的垂直坐標,即 y 坐標。left:滾動后頁面左上角的水平坐標,即 x 坐標。behavior:字符串,表示滾動的方式,有三個可能值(smooth、instant、auto),默認值為auto。
window.scrollTo({
top: 1000,
behavior: 'smooth'
});
window.scroll()方法是window.scrollTo()方法的別名。
window.scrollBy()方法用於將網頁滾動指定距離(單位像素)。它接受兩個參數:水平向右滾動的像素,垂直向下滾動的像素。
window.scrollBy(0, window.innerHeight)
上面代碼用於將網頁向下滾動一屏。
如果不是要滾動整個文檔,而是要滾動某個元素,可以使用下面三個屬性和方法。
- Element.scrollTop
- Element.scrollLeft
- Element.scrollIntoView()
window.print()
window.print方法會跳出打印對話框,與用戶點擊菜單里面的“打印”命令效果相同。
常見的打印按鈕代碼如下。
document.getElementById('printLink').onclick = function () {
window.print();
}
非桌面設備(比如手機)可能沒有打印功能,這時可以這樣判斷。
if (typeof window.print === 'function') {
// 支持打印功能
}
window.getSelection()
window.getSelection方法返回一個Selection對象,表示用戶現在選中的文本
var selObj = window.getSelection();
使用Selection對象的toString方法可以得到選中的文本。
var selectedText = selObj.toString();
window.getComputedStyle(),window.matchMedia()
window.getComputedStyle()方法接受一個元素節點作為參數,返回一個包含該元素的最終樣式信息的對象
window.matchMedia()方法用來檢查 CSS 的mediaQuery語句
事件
window對象可以接收以下事件。
load 事件和 onload 屬性
load事件發生在文檔在瀏覽器窗口加載完畢時。window.onload屬性可以指定這個事件的回調函數。
window.onload = function() {
var elements = document.getElementsByClassName('example');
for (var i = 0; i < elements.length; i++) {
var elt = elements[i];
// ...
}
};
上面代碼在網頁加載完畢后,獲取指定元素並進行處理。
error 事件和 onerror 屬性
瀏覽器腳本發生錯誤時,會觸發window對象的error事件。我們可以通過window.onerror屬性對該事件指定回調函數。
window.onerror = function (message, filename, lineno, colno, error) {
console.log("出錯了!--> %s", error.stack);
};
由於歷史原因,window的error事件的回調函數不接受錯誤對象作為參數,而是一共可以接受五個參數,它們的含義依次如下。
- 出錯信息
- 出錯腳本的網址
- 行號
- 列號
- 錯誤對象
老式瀏覽器只支持前三個參數。
並不是所有的錯誤,都會觸發 JavaScript 的error事件(即讓 JavaScript 報錯)。一般來說,只有 JavaScript 腳本的錯誤,才會觸發這個事件,而像資源文件不存在之類的錯誤,都不會觸發。
下面是一個例子,如果整個頁面未捕獲錯誤超過3個,就顯示警告。
window.onerror = function(msg, url, line) {
if (onerror.num++ > onerror.max) {
alert('ERROR: ' + msg + '\n' + url + ':' + line);
return true;
}
}
onerror.max = 3;
onerror.num = 0;
需要注意的是,如果腳本網址與網頁網址不在同一個域(比如使用了 CDN),瀏覽器根本不會提供詳細的出錯信息,只會提示出錯,錯誤類型是“Script error.”,行號為0,其他信息都沒有。這是瀏覽器防止向外部腳本泄漏信息。一個解決方法是在腳本所在的服務器,設置Access-Control-Allow-Origin的 HTTP 頭信息。
Access-Control-Allow-Origin: *
然后,在網頁的<script>標簽中設置crossorigin屬性。
<script crossorigin="anonymous" src="//example.com/file.js"></script>
上面代碼的crossorigin="anonymous"表示,讀取文件不需要身份信息,即不需要 cookie 和 HTTP 認證信息。如果設為crossorigin="use-credentials",就表示瀏覽器會上傳 cookie 和 HTTP 認證信息,同時還需要服務器端打開 HTTP 頭信息Access-Control-Allow-Credentials。
Navigator對象
window.navigator屬性指向一個包含瀏覽器和系統信息的 Navigator 對象。腳本通過這個屬性了解用戶的環境信息。
Navigator.userAgent屬性
navigator.userAgent屬性返回瀏覽器的 User Agent 字符串,表示瀏覽器的廠商和版本信息。
通過userAgent屬性識別瀏覽器,不是一個好辦法。因為必須考慮所有的情況(不同的瀏覽器,不同的版本),非常麻煩,而且用戶可以改變這個字符串。這個字符串的格式並無統一規定,也無法保證未來的適用性,各種上網設備層出不窮,難以窮盡。所以,現在一般不再通過它識別瀏覽器了,而是使用“功能識別”方法,即逐一測試當前瀏覽器是否支持要用到的 JavaScript 功能。
不過,通過userAgent可以大致准確地識別手機瀏覽器,方法就是測試是否包含mobi字符串。
var ua = navigator.userAgent.toLowerCase();
if (/mobi/i.test(ua)) {
// 手機瀏覽器
} else {
// 非手機瀏覽器
}
Navigator.plugins
Navigator.plugins屬性返回一個類似數組的對象,成員是 Plugin 實例對象,表示瀏覽器安裝的插件,比如 Flash、ActiveX 等。
var pluginsLength = navigator.plugins.length;
for (var i = 0; i < pluginsLength; i++) {
console.log(navigator.plugins[i].name);
console.log(navigator.plugins[i].filename);
console.log(navigator.plugins[i].description);
console.log(navigator.plugins[i].version);
}
Navigator.platform
Navigator.platform屬性返回用戶的操作系統信息,比如MacIntel、Win32、Linux x86_64等 。
Navigator.onLine
navigator.onLine屬性返回一個布爾值,表示用戶當前在線還是離線(瀏覽器斷線)。
有時,瀏覽器可以連接局域網,但是局域網不能連通外網。這時,有的瀏覽器的onLine屬性會返回true,所以不能假定只要是true,用戶就一定能訪問互聯網。不過,如果是false,可以斷定用戶一定離線。
用戶變成在線會觸發online事件,變成離線會觸發offline事件,可以通過window.ononline和window.onoffline指定這兩個事件的回調函數。
window.addEventListener('offline', function(e) { console.log('offline'); });
window.addEventListener('online', function(e) { console.log('online'); });
Navigator.language,Navigator.languages
Navigator.language屬性返回一個字符串,表示瀏覽器的首選語言。該屬性只讀。
navigator.language // "en"
Navigator.languages屬性返回一個數組,表示用戶可以接受的語言。Navigator.language總是這個數組的第一個成員。HTTP 請求頭信息的Accept-Language字段,就來自這個數組。
navigator.languages // ["en-US", "en", "zh-CN", "zh", "zh-TW"]
如果這個屬性發生變化,就會在window對象上觸發languagechange事件。
Navigator.geolocation
Navigator.geolocation屬性返回一個 Geolocation 對象,包含用戶地理位置的信息。注意,該 API 只有在 HTTPS 協議下可用,否則調用下面方法時會報錯。
Geolocation 對象提供下面三個方法。
- Geolocation.getCurrentPosition():得到用戶的當前位置
- Geolocation.watchPosition():監聽用戶位置變化
- Geolocation.clearWatch():取消
watchPosition()方法指定的監聽函數
注意,調用這三個方法時,瀏覽器會跳出一個對話框,要求用戶給予授權。
Navigator.cookieEnabled
Navigator.cookieEnabled屬性返回一個布爾值,表示瀏覽器的 Cookie 功能是否打開。
navigator.cookieEnabled // true
注意,這個屬性反映的是瀏覽器總的特性,與是否儲存某個具體的網站的 Cookie 無關。用戶可以設置某個網站不得儲存 Cookie,這時cookieEnabled返回的還是true。
Screen 對象
Screen 對象表示當前窗口所在的屏幕,提供顯示設備的信息。window.screen屬性指向這個對象。
該對象有下面的屬性。
Screen.height:瀏覽器窗口所在的屏幕的高度(單位像素)。除非調整顯示器的分辨率,否則這個值可以看作常量,不會發生變化。顯示器的分辨率與瀏覽器設置無關,縮放網頁並不會改變分辨率。Screen.width:瀏覽器窗口所在的屏幕的寬度(單位像素)。Screen.availHeight:瀏覽器窗口可用的屏幕高度(單位像素)。因為部分空間可能不可用,比如系統的任務欄或者 Mac 系統屏幕底部的 Dock 區,這個屬性等於height減去那些被系統組件的高度。Screen.availWidth:瀏覽器窗口可用的屏幕寬度(單位像素)。Screen.pixelDepth:整數,表示屏幕的色彩位數,比如24表示屏幕提供24位色彩。Screen.colorDepth:Screen.pixelDepth的別名。嚴格地說,colorDepth 表示應用程序的顏色深度,pixelDepth 表示屏幕的顏色深度,絕大多數情況下,它們都是同一件事。Screen.orientation:返回一個對象,表示屏幕的方向。該對象的type屬性是一個字符串,表示屏幕的具體方向,landscape-primary表示橫放,landscape-secondary表示顛倒的橫放,portrait-primary表示豎放,portrait-secondary。
下面的例子保證屏幕分辨率大於 1024 x 768。
if (window.screen.width >= 1024 && window.screen.height >= 768) {
// 分辨率不低於 1024x768
}
下面是根據屏幕的寬度,將用戶導向不同網頁的代碼。
if ((screen.width <= 800) && (screen.height <= 600)) {
window.location.replace('small.html');
} else {
window.location.replace('wide.html');
}
Location對象
Location對象是瀏覽器提供的原生對象,提供 URL 相關的信息和操作方法。通過window.location和document.location屬性,可以拿到這個對象。
相關屬性
Location對象提供以下屬性。
Location.href:整個 URL。Location.protocol:當前 URL 的協議,包括冒號(:)。Location.host:主機,包括冒號(:)和端口(默認的80端口和443端口會省略)。Location.hostname:主機名,不包括端口。Location.port:端口號。Location.pathname:URL 的路徑部分,從根路徑/開始。Location.search:查詢字符串部分,從問號?開始。Location.hash:片段字符串部分,從#開始。Location.username:域名前面的用戶名。Location.password:域名前面的密碼。Location.origin:URL 的協議、主機名和端口。
// 當前網址為
// http://user:passwd@www.example.com:4097/path/a.html?x=111#part1
document.location.href
// "http://user:passwd@www.example.com:4097/path/a.html?x=111#part1"
document.location.protocol
// "http:"
document.location.host
// "www.example.com:4097"
document.location.hostname
// "www.example.com"
document.location.port
// "4097"
document.location.pathname
// "/path/a.html"
document.location.search
// "?x=111"
document.location.hash
// "#part1"
document.location.username
// "user"
document.location.password
// "passwd"
document.location.origin
// "http://user:passwd@www.example.com:4097"
這些屬性里面,只有origin屬性是只讀的,其他屬性都可寫。
注意,如果對Location.href寫入新的 URL 地址,瀏覽器會立刻跳轉到這個新地址。
// 跳轉到新網址
document.location.href = 'http://www.example.com';
這個特性常常用於讓網頁自動滾動到新的錨點。
document.location.href = '#top';
// 等同於
document.location.hash = '#top';
直接改寫location,相當於寫入href屬性。
document.location = 'http://www.example.com';
// 等同於
document.location.href = 'http://www.example.com';
另外,Location.href屬性是瀏覽器唯一允許跨域寫入的屬性,即非同源的窗口可以改寫另一個窗口(比如子窗口與父窗口)的Location.href屬性,導致后者的網址跳轉。Location的其他屬性都不允許跨域寫入。
相關方法
1、Location.assign()
assign方法接受一個 URL 字符串作為參數,使得瀏覽器立刻跳轉到新的 URL。如果參數不是有效的 URL 字符串,則會報錯。
// 跳轉到新的網址
document.location.assign('http://www.example.com')
2、Location.replace()
replace方法接受一個 URL 字符串作為參數,使得瀏覽器立刻跳轉到新的 URL。如果參數不是有效的 URL 字符串,則會報錯。
它與assign方法的差異在於,replace會在瀏覽器的瀏覽歷史History里面刪除當前網址,也就是說,一旦使用了該方法,后退按鈕就無法回到當前網頁了,相當於在瀏覽歷史里面,使用新的 URL 替換了老的 URL。它的一個應用是,當腳本發現當前是移動設備時,就立刻跳轉到移動版網頁。
// 跳轉到新的網址
document.location.replace('http://www.example.com')
3、Location.reload()
reload方法使得瀏覽器重新加載當前網址,相當於按下瀏覽器的刷新按鈕。
它接受一個布爾值作為參數。如果參數為true,瀏覽器將向服務器重新請求這個網頁,並且重新加載后,網頁將滾動到頭部(即scrollTop === 0)。如果參數是false或為空,瀏覽器將從本地緩存重新加載該網頁,並且重新加載后,網頁的視口位置是重新加載前的位置。
// 向服務器重新請求當前網址
window.location.reload(true);
4、Location.toString()
toString方法返回整個 URL 字符串,相當於讀取Location.href屬性。
History 對象
window.history屬性指向History對象,表示當前窗口的瀏覽歷史。
History對象保存了當前窗口訪問過的所有的頁面網址。下面代碼表示當前窗口一共訪問過3個網址。
window.history.length // 3
出於安全因素的考慮,瀏覽器不允許我們讀取這些地址,但是卻允許通過指定的方法在地址之間進行導航。
// 后退到前一個網址
history.back()
// 等同於
history.go(-1)
瀏覽器工具欄的“前進”和“后退”按鈕,其實就是對 History 對象進行操作。
屬性
當前對象主要有兩個屬性。
- History.length: 當前窗口訪問過的網址數量(包括當前網頁)
- History.state : History 堆棧最上層的狀態值
// 當前窗口訪問過多少個網頁
window.history.length // 1
// History 對象的當前狀態
// 通常是 undefined,即未設置
window.history.state // undefined
方法
**1、History.back()、History.forward()、History.go() **
這三個方法用於在歷史之中移動。
History.back():移動到上一個網址,等同於點擊瀏覽器的后退鍵。對於第一個訪問的網址,該方法無效果。History.forward():移動到下一個網址,等同於點擊瀏覽器的前進鍵。對於最后一個訪問的網址,該方法無效果。History.go():接受一個整數作為參數,以當前網址為基准,移動到參數指定的網址,比如go(1)相當於forward(),go(-1)相當於back()。如果參數超過實際存在的網址范圍,該方法無效果;如果不指定參數,默認參數為0,相當於刷新當前頁面。
history.back();
history.forward();
history.go(-2);
history.go(0)相當於刷新當前頁面。
history.go(0); // 刷新當前頁面
注意,移動到以前訪問過的頁面時,頁面通常是從瀏覽器緩存之中加載,而不是重新要求服務器發送新的網頁。
2、History.pushState()
History.pushState()方法用於在歷史中添加一條記錄。
window.history.pushState(state, title, url)
該方法接受三個參數,依次為:
state:一個與添加的記錄相關聯的狀態對象,主要用於popstate事件。該事件觸發時,該對象會傳入回調函數。也就是說,瀏覽器會將這個對象序列化以后保留在本地,重新載入這個頁面的時候,可以拿到這個對象。如果不需要這個對象,此處可以填null。title:新頁面的標題。但是,現在所有瀏覽器都忽視這個參數,所以這里可以填空字符串。url:新的網址,必須與當前頁面處在同一個域。瀏覽器的地址欄將顯示這個網址。
假定當前網址是example.com/1.html,使用pushState()方法在瀏覽記錄(History 對象)中添加一個新記錄。
var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
添加新記錄后,瀏覽器地址欄立刻顯示example.com/2.html,但並不會跳轉到2.html,甚至也不會檢查2.html是否存在,它只是成為瀏覽歷史中的最新記錄。這時,在地址欄輸入一個新的地址(比如訪問google.com),然后點擊了倒退按鈕,頁面的 URL 將顯示2.html;你再點擊一次倒退按鈕,URL 將顯示1.html。
總之,pushState()方法不會觸發頁面刷新,只是導致 History 對象發生變化,地址欄會有反應。
使用該方法之后,就可以用History.state屬性讀出狀態對象。
var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
history.state // {foo: "bar"}
如果pushState的 URL 參數設置了一個新的錨點值(即hash),並不會觸發hashchange事件。反過來,如果 URL 的錨點值變了,則會在 History 對象創建一條瀏覽記錄。
如果pushState()方法設置了一個跨域網址,則會報錯。
// 報錯
// 當前網址為 http://example.com
history.pushState(null, '', 'https://twitter.com/hello');
上面代碼中,pushState想要插入一個跨域的網址,導致報錯。這樣設計的目的是,防止惡意代碼讓用戶以為他們是在另一個網站上,因為這個方法不會導致頁面跳轉。
