[TOC]
## 概述
JavaScript的所有對象都存在于一個運行環境之中,這個運行環境本身也是對象,稱為“頂層對象”。這就是說,JavaScript的所有對象,都是“頂層對象”的下屬。不同的運行環境有不同的“頂層對象”,在瀏覽器環境中,這個頂層對象就是window對象(w為小寫)。
所有瀏覽器環境的全局變量,都是window對象的屬性。
~~~
var a = 1;
window.a // 1
~~~
可以簡單理解成,window就是指當前的瀏覽器窗口。
## window對象的屬性
### window.name屬性
window.name屬性用于設置當前瀏覽器窗口的名字。它有一個特點,就是瀏覽器刷新后,該屬性保持不變。所以,可以把值存放在該屬性內,然后跨頁面、甚至跨域名使用。當然,這個值有可能被其他網站的頁面改寫。
~~~
window.name = "Hello World!";
console.log(window.name);
~~~
各個瀏覽器對這個值的儲存容量有所不同,但是一般來說,可以高達幾MB。
該屬性只能保存字符串,且當瀏覽器窗口關閉后,所保存的值就會消失。因此局限性比較大,但是與iFrame窗口通信時,非常有用。
### window.innerHeight屬性,window.innerWidth屬性
這兩個屬性返回網頁的CSS布局占據的瀏覽器窗口的高度和寬度,單位為像素。很顯然,當用戶放大網頁的時候(比如將網頁從100%的大小放大為200%),這兩個屬性會變小。
注意,這兩個屬性值包括滾動條的高度和寬度。
### window.pageXOffset屬性,window.pageYOffset屬性
window.pageXOffset屬性返回頁面的水平滾動距離,window.pageYOffset屬性返回頁面的垂直滾動距離。這兩個屬性的單位為像素。
### iframe元素
window.frames返回一個類似數組的對象,成員為頁面內的所有框架,包括frame元素和iframe元素。需要注意的是,window.frames的每個成員對應的是框架內的窗口(即框架的window對象),獲取每個框架的DOM樹,需要使用window.frames[0].document。
~~~
var iframe = window.getElementsByTagName("iframe")[0];
var iframe_title = iframe.contentWindow.title;
~~~
上面代碼用于獲取框架頁面的標題。
iframe元素遵守同源政策,只有當父頁面與框架頁面來自同一個域名,兩者之間才可以用腳本通信,否則只有使用window.postMessage方法。
在iframe框架內部,使用window.parent指向父頁面。
### Navigator對象
Window對象的Navigator屬性,指向一個包含瀏覽器相關信息的對象。
(1)Navigator.userAgent屬性
Navigator.userAgent屬性返回瀏覽器的User-Agent字符串,用來標示瀏覽器的種類。下面是Chrome瀏覽器的User-Agent。
~~~
navigator.userAgent
// "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36"
~~~
通過userAgent屬性識別瀏覽器,不是一個好辦法。因為必須考慮所有的情況(不同的瀏覽器,不同的版本),非常麻煩,而且無法保證未來的適用性,更何況各種上網設備層出不窮,難以窮盡。所以,現在一般不再識別瀏覽器了,而是使用“功能識別”方法,即逐一測試當前瀏覽器是否支持要用到的JavaScript功能。
不過,通過userAgent可以大致準確地識別手機瀏覽器,方法就是測試是否包含“mobi”字符串。
~~~
var ua = navigator.userAgent.toLowerCase();
if (/mobi/i.test(ua)) {
// 手機瀏覽器
} else {
// 非手機瀏覽器
}
~~~
如果想要識別所有移動設備的瀏覽器,可以測試更多的特征字符串。
~~~
/mobi|android|touch|mini/i.test(ua)
~~~
(2)navigator.plugins屬性
navigator.plugins屬性返回一個類似數組的對象,成員是瀏覽器安裝的插件,比如Flash、ActiveX等。
### screen對象
screen對象包含了顯示設備的信息。
~~~
// 顯示設備的高度,單位為像素
screen.height
// 1920
// 顯示設備的寬度,單位為像素
screen.width
// 1080
~~~
一般使用以上兩個屬性,了解設備的分辨率。上面代碼顯示,某設備的分辨率是1920x1080。
除非調整顯示器的分辨率,否則這兩個值可以看作常量,不會發生變化。顯示器的分辨率與瀏覽器設置無關,縮放網頁并不會改變分辨率。
下面是根據屏幕分辨率,將用戶導向不同網頁的代碼。
~~~
if ((screen.width<=800) && (screen.height<=600)) {
window.location.replace('small.html');
} else {
window.location.replace('wide.html');
}
~~~
## window對象的方法
### URL的編碼/解碼方法
JavaScript提供四個URL的編碼/解碼方法。
* decodeURI()
* decodeURIComponent()
* encodeURI()
* encodeURIComponent()
### window.getComputedStyle方法
getComputedStyle方法接受一個HTML元素作為參數,返回一個包含該HTML元素的最終樣式信息的對象。詳見《DOM》一章的CSS章節。
### window.matchMedia方法
window.matchMedia方法用來檢查CSS的mediaQuery語句。詳見《DOM》一章的CSS章節。
## window對象的事件
### window.onerror
瀏覽器腳本發生錯誤時,會觸發window對象的error事件。我們可以通過`window.onerror`屬性對該事件指定回調函數。
~~~
window.onerror = function (message, filename, lineno, colno, error) {
console.log("出錯了!--> %s", error.stack);
};
~~~
error事件的回調函數,一共可以有五個參數,它們的含義依次如下。
* 出錯信息
* 出錯腳本的網址
* 行號
* 列號
* 錯誤對象
老式瀏覽器只支持前三個參數。
需要注意的是,如果腳本網址與網頁網址不在同一個域(比如使用了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。
并不是所有的錯誤,都會觸發JavaScript的error事件(即讓JavaScript報錯),只限于以下三類事件。
* JavaScript語言錯誤
* JavaScript腳本文件不存在
* 圖像文件不存在
以下兩類事件不會觸發JavaScript的error事件。
* CSS文件不存在
* iframe文件不存在
## alert(),prompt(),confirm()
alert()、prompt()、confirm()都是瀏覽器用來與用戶互動的方法。它們會彈出不同的對話框,要求用戶做出回應。
需要注意的是,alert()、prompt()、confirm()這三個方法彈出的對話框,都是瀏覽器統一規定的式樣,是無法定制的。
alert方法彈出的對話框,只有一個“確定”按鈕,往往用來通知用戶某些信息。
~~~
// 格式
alert(message);
// 實例
alert("Hello World");
~~~
用戶只有點擊“確定”按鈕,對話框才會消失。在對話框彈出期間,瀏覽器窗口處于凍結狀態,如果不點“確定”按鈕,用戶什么也干不了。
prompt方法彈出的對話框,在提示文字的下方,還有一個輸入框,要求用戶輸入信息,并有“確定”和“取消”兩個按鈕。它往往用來獲取用戶輸入的數據。
~~~
// 格式
var result = prompt(text[, default]);
// 實例
var result = prompt('您的年齡?', 25)
~~~
上面代碼會跳出一個對話框,文字提示為“您的年齡?”,要求用戶在對話框中輸入自己的年齡(默認顯示25)。
prompt方法的返回值是一個字符串(有可能為空)或者null,具體分成三種情況。
1. 用戶輸入信息,并點擊“確定”,則用戶輸入的信息就是返回值。
2. 用戶沒有輸入信息,直接點擊“確定”,則輸入框的默認值就是返回值。
3. 用戶點擊了“取消”(或者按了Escape按鈕),則返回值是null。
prompt方法的第二個參數是可選的,但是如果不提供的話,IE瀏覽器會在輸入框中顯示undefined。因此,最好總是提供第二個參數,作為輸入框的默認值。
confirm方法彈出的對話框,除了提示信息之外,只有“確定”和“取消”兩個按鈕,往往用來征詢用戶的意見。
~~~
// 格式
var result = confirm(message);
// 實例
var result = confirm("你最近好嗎?");
~~~
上面代碼彈出一個對話框,上面只有一行文字“你最近好嗎?”,用戶選擇點擊“確定”或“取消”。
confirm方法返回一個布爾值,如果用戶點擊“確定”,則返回true;如果用戶點擊“取消”,則返回false。
## 參考鏈接
* Karl Dubost,?[User-Agent detection, history and checklist](https://hacks.mozilla.org/2013/09/user-agent-detection-history-and-checklist/)
* Conrad Irwin,?[JS stacktraces. The good, the bad, and the ugly](https://bugsnag.com/blog/js-stacktraces/)
* Daniel Lee,?[How to catch JavaScript Errors with window.onerror (even on Chrome and Firefox)](http://danlimerick.wordpress.com/2014/01/18/how-to-catch-javascript-errors-with-window-onerror-even-on-chrome-and-firefox/)
- 第一章 導論
- 1.1 前言
- 1.2 為什么學習JavaScript?
- 1.3 JavaScript的歷史
- 第二章 基本語法
- 2.1 語法概述
- 2.2 數值
- 2.3 字符串
- 2.4 對象
- 2.5 數組
- 2.6 函數
- 2.7 運算符
- 2.8 數據類型轉換
- 2.9 錯誤處理機制
- 2.10 JavaScript 編程風格
- 第三章 標準庫
- 3.1 Object對象
- 3.2 Array 對象
- 3.3 包裝對象和Boolean對象
- 3.4 Number對象
- 3.5 String對象
- 3.6 Math對象
- 3.7 Date對象
- 3.8 RegExp對象
- 3.9 JSON對象
- 3.10 ArrayBuffer:類型化數組
- 第四章 面向對象編程
- 4.1 概述
- 4.2 封裝
- 4.3 繼承
- 4.4 模塊化編程
- 第五章 DOM
- 5.1 Node節點
- 5.2 document節點
- 5.3 Element對象
- 5.4 Text節點和DocumentFragment節點
- 5.5 Event對象
- 5.6 CSS操作
- 5.7 Mutation Observer
- 第六章 瀏覽器對象
- 6.1 瀏覽器的JavaScript引擎
- 6.2 定時器
- 6.3 window對象
- 6.4 history對象
- 6.5 Ajax
- 6.6 同域限制和window.postMessage方法
- 6.7 Web Storage:瀏覽器端數據儲存機制
- 6.8 IndexedDB:瀏覽器端數據庫
- 6.9 Web Notifications API
- 6.10 Performance API
- 6.11 移動設備API
- 第七章 HTML網頁的API
- 7.1 HTML網頁元素
- 7.2 Canvas API
- 7.3 SVG 圖像
- 7.4 表單
- 7.5 文件和二進制數據的操作
- 7.6 Web Worker
- 7.7 SSE:服務器發送事件
- 7.8 Page Visibility API
- 7.9 Fullscreen API:全屏操作
- 7.10 Web Speech
- 7.11 requestAnimationFrame
- 7.12 WebSocket
- 7.13 WebRTC
- 7.14 Web Components
- 第八章 開發工具
- 8.1 console對象
- 8.2 PhantomJS
- 8.3 Bower:客戶端庫管理工具
- 8.4 Grunt:任務自動管理工具
- 8.5 Gulp:任務自動管理工具
- 8.6 Browserify:瀏覽器加載Node.js模塊
- 8.7 RequireJS和AMD規范
- 8.8 Source Map
- 8.9 JavaScript 程序測試
- 第九章 JavaScript高級語法
- 9.1 Promise對象
- 9.2 有限狀態機
- 9.3 MVC框架與Backbone.js
- 9.4 嚴格模式
- 9.5 ECMAScript 6 介紹
- 附錄
- 10.1 JavaScript API列表
- 草稿一:函數庫
- 11.1 Underscore.js
- 11.2 Modernizr
- 11.3 Datejs
- 11.4 D3.js
- 11.5 設計模式
- 11.6 排序算法
- 草稿二:jQuery
- 12.1 jQuery概述
- 12.2 jQuery工具方法
- 12.3 jQuery插件開發
- 12.4 jQuery.Deferred對象
- 12.5 如何做到 jQuery-free?
- 草稿三:Node.js
- 13.1 Node.js 概述
- 13.2 CommonJS規范
- 13.3 package.json文件
- 13.4 npm模塊管理器
- 13.5 fs 模塊
- 13.6 Path模塊
- 13.7 process對象
- 13.8 Buffer對象
- 13.9 Events模塊
- 13.10 stream接口
- 13.11 Child Process模塊
- 13.12 Http模塊
- 13.13 assert 模塊
- 13.14 Cluster模塊
- 13.15 os模塊
- 13.16 Net模塊和DNS模塊
- 13.17 Express框架
- 13.18 Koa 框架