8 BOM

本章內(nèi)容

  • 理解window對象--BOM 的核心
  • 控制窗口,框架和彈出窗口
  • 利用location對象中的頁面信息
  • 使用navigator對象了解瀏覽器

8.1 window 對象

BOM的核心對象是window则涯,它表示瀏覽器的一個實例瓦戚。在瀏覽器中一也,window對象有雙重角色获洲,它既是通過JavaScript訪問瀏覽器窗口的一個接口擒滑,又是 ECMAScript 規(guī)定的Global對象情萤。這意味著在網(wǎng)頁中定義的任何一個對象帆精,變量和函數(shù)较屿,都以window作為其Global對象,因此有權(quán)訪問parseInt()等方法卓练。

8.1.1 全局作用域

所有在全局作用域中聲明的變量隘蝎,函數(shù)都會變成window對象的屬性和方法。
拋開全局變量會成為window對象的屬性不談襟企,定義全局變量與在window對象上直接定義屬性還是有一點差別:全局變量不能通過delete操作符刪除嘱么,而直接在window對象上的定義的屬性可以。
另外顽悼,還要記住一件事:嘗試訪問未聲明的變量會拋出錯誤曼振,但是通過查詢window對象,可以知道某個可能未聲明的變量是否存在蔚龙。

//這里會拋出錯誤冰评,因為`oldValue`未定義
var newValue = oldValue;
//這里不會拋出錯誤,因為這是一次屬性查詢
//newValue 的值是 undefined
var newValue = window.oldValue;

8.1.2 窗口關(guān)系及框架

如果頁面中包含框架木羹,則每個框架都有自己的 window對象甲雅,并且保存在frames集合中。在frames集合中坑填,可以通過數(shù)值索引或者框架名稱來訪問相應(yīng)的window對象抛人。每個window對象都有一個name屬性,其中包含框架的名稱脐瑰。
top對象始終指向最高(最外)層的框架函匕。也就是瀏覽器窗口。使用它可以確保在一個框架中正確地訪問另一個框架蚪黑。因為對于在一個框架中編寫的任何代碼來說盅惜,其中的window對象指向的都是那個框架的特定實例,而非最高層的框架忌穿。

8.1.3 窗口位置

var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;

8.1.4 窗口大小

outerWidthouterHeight返回瀏覽器窗口本身的尺寸抒寂;而innerWidthinnerHeight則表示該容器中頁面視圖區(qū)的大小(減去邊框?qū)挾龋?br> document.documentElement.clientWidthdocument.documentElement.clientHeight;document.body.clientWidthdocument.body.clientHeight掠剑。

8.1.5 導(dǎo)航和打開窗口

使用window.open()方法既可以導(dǎo)航到一個特定的 URL屈芜,也可以打開一個新的瀏覽器窗口。這個方法可以接收 4 個參數(shù):要加載的 URL朴译、窗口目標井佑、一個特性字符串以及一個表示新頁面是否取代瀏覽器歷史紀錄中當前加載頁面的布爾值。通常只需傳遞第一個參數(shù)眠寿,最后一個參數(shù)只在不打開新窗口的情況下使用躬翁。
如果傳遞了第二個參數(shù),而且該參數(shù)是已有窗口或框架的名稱盯拱,那么就會在具有該名稱的窗口或框架中加載第一個參數(shù)指定的 URL盒发。

//等同于<a  target="topFrame"></a>
window.open("http://www.wrox.com/", "topFrame");

如果名叫 "topFrame" 的窗口或者框架,就會在該窗口或框架加載這個 URL狡逢;否則宁舰,就會創(chuàng)建一個新窗口并將其命名為 "topFrame"。此外奢浑,第二個參數(shù)也可以是下列任何一個特殊的窗口名稱: _self蛮艰、_parent、_top 或 _blank雀彼。

  1. 彈出窗口
    如果第二個參數(shù)并不是已存在的窗口或框架壤蚜,那么該方法就會根據(jù)在第三個參數(shù)位置上傳入的字符串創(chuàng)建一個新窗口或新標簽頁。如果沒有傳入第三個參數(shù)详羡,那么就會打開一個帶有全部默認設(shè)置的新瀏覽器窗口仍律。在不打開新窗口的情況下,會忽略第三個參數(shù)实柠。
    第三個參數(shù)是一個逗號分隔的設(shè)置字符串水泉,表示在新窗口中都顯示那些特性。
window.open("http://www.wrox.com/","wroxWindow", "height=400,width=400,top=0,left=10,resizable=yes");

window.open()方法會返回一個指向新窗口的引用窒盐。引用的對象與其他window對象大致相似草则,但可以對其進行更多控制。

var wroxWin = window.open("http://wrox.com/","wroxWindow");
wroxWin.resizeTo(500,500);
wroxWin.moveTo(100,100);
wroxWin.close();
  1. 安全機制
  2. 彈出窗口屏蔽程序
var wrox = window.open("http://www.wrox.com", "_blank");
if(wroxWin == null) {
  alert("The popup was blocked!");
}

如果是瀏覽器擴展或其他程序阻止的彈出窗口蟹漓,那么window.open()通常會拋出一個錯誤炕横。

var blocked = false;
try {
  var wrox = window.open("http://www.wrox.com", "_blank");
  if (wroxWin == null) {
    blocked = true;
  } 
}catch (ex) {
  blocked = true;
}
if (blocked) {
  alert("The popup was blocked!");
}

8.1.6 間歇調(diào)用和超時調(diào)用

超時調(diào)用需要使用window對象的setTimeout()方法,它接受兩個參數(shù):要執(zhí)行的代碼和以毫秒表示的時間(即在執(zhí)行代碼前需要等待多少毫秒)葡粒。其中份殿,第一個參數(shù)可以是一個包含 JavaScript 代碼的字符串膜钓,也可以是一個函數(shù)。

//不推薦傳遞字符串
setTimeout("alert("Hello world!")", 1000);
//推薦的調(diào)用方式
setTimeout(function(){alert("hello world!")}, 1000);

第二個參數(shù)告訴 JavaScript 再過多長時間把當前任務(wù)添加到隊列中卿嘲。如果隊列是空的颂斜,那么添加的代碼會立即執(zhí)行,否則拾枣,得等前面的代碼執(zhí)行完畢之后在執(zhí)行沃疮。
調(diào)用 setTimeout()之后,該方法會返回一個數(shù)值 ID梅肤,表示超時調(diào)用司蔬。這個超時調(diào)用 ID 是計劃執(zhí)行代碼的唯一標識符,可以通過它來取消超時調(diào)用姨蝴。

var timeoutId = setTimeout(function () {alert("hello world!");}, 1000);
// 
clearTimeout(timeoutId);

間歇調(diào)用與超時調(diào)用類似俊啼,只不過它會按照指定的時間間隔重復(fù)執(zhí)行代碼,直至間歇調(diào)用被取消或者頁面被卸載似扔。

setInterval(function(){alert("hello world!");}, 1000);
var intervalId = ...
clearInterval(intervalId);

使用超時調(diào)用來模擬間歇調(diào)用是一種最佳模式吨些,因為后一個間歇調(diào)用可能會在前一個間歇調(diào)用結(jié)束之前啟動。所以炒辉,最好不要使用間歇調(diào)用豪墅。

8.1.7 系統(tǒng)對話框

瀏覽器通過 alert()confirm()prompt()方法可以調(diào)用系統(tǒng)對話框向用戶顯示消息黔寇。系統(tǒng)對話框與在瀏覽器中顯示的網(wǎng)頁沒有關(guān)系偶器,也不包含 HTML。它們的外觀由操作系統(tǒng)及(或)瀏覽器設(shè)置決定缝裤,而不是由 CSS 決定屏轰。此外,通過這幾個方法打開的對話框都是同步和模態(tài)的憋飞。也就是說霎苗,顯示這些對話框的時候代碼會停止執(zhí)行,而關(guān)掉這些對話框后代碼又會恢復(fù)執(zhí)行榛做。
為了確認用戶是單擊了 OK 還是 Cancel唁盏,可以檢查confirm()方法返回的布爾值。

if (confirm("are you okay?")) {
  alert("haha!");
} else {
  alert("eee!");
}

prompt()方法生成的是一個“提示”框检眯,用于提示用戶輸入一些文本厘擂。該方法接受兩個參數(shù):要顯示給用戶的文本提示和文本輸入域的默認值(可以是一個空字符串)。
如果用戶單擊了 OK 按鈕锰瘸,則prompt()返回文本輸入框的值刽严;如果不是則返回null

8.2 location 對象

location對象既是window對象的屬性避凝,也是document對象的屬性舞萄;換句話說眨补,window.locationdocument.location引用的是同一個對象。

8.2.1 查詢字符串參數(shù)

可以像下面這樣創(chuàng)建一個函數(shù)倒脓,用以解析查詢字符串渤涌,然后返回包含所有參數(shù)的一個對象:

function getQueryStringArgs () {
  //取得查詢字符串并去掉開頭的問號
  var qs = (location.search.length > 0 ? location.search.substring(1) : "");
  //保存數(shù)據(jù)的對象
  var args = {};
  //取得每一項
  var items = qs.lenth ? qs.split("&") : [];
  var item = null;
  var name = null;
  var value = null;
  var i = 0;
  var len = items.length;
  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;
}

8.2.2 位置操作

location.assign("http://www.wrox.com");
location.;
...

使用replace()方法后,用戶不能回到前一個頁面把还。

location.reload();  //重新加載(有可能從緩存中加載)
location.reload(true);  //重新加載(從服務(wù)器中加載)

最好將reload放在代碼的最后一行。

8.3 navigator 對象

現(xiàn)已成為識別客戶端瀏覽器的事實標準茸俭。

8.3.1 檢測插件

對于非 IE 瀏覽器吊履,可以使用plugins數(shù)組來達到這個目的。該數(shù)組中的每一項都包含下列屬性调鬓。

  • name: 插件的名字艇炎。
  • description: 插件的描述。
  • filename: 插件的文件名腾窝。
  • length: 插件所處理的 MIME 類型數(shù)量缀踪。

檢測 IE 中的插件比較麻煩。在 IE 中檢測插件的唯一方式就是使用專有的ActiveXObject類型虹脯,并嘗試創(chuàng)建一個特定插件的實例驴娃。要想檢查特定的插件,就必須知道其 COM 標識符循集。

function hasIEPlugin (name) {
  try {
    new ActiveXObject(name);
    return true;
  } catch (ex) {
    return false;
  }
}
//檢測 Flash
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash"));
//檢測 QuickTime
alert(hasIEPlugin("QuickTime.QuickTime"));
//檢測所有瀏覽器中的 QuickTime
function hasQuickTime() {
  var result = hasPlugin("QuickTime");
  if(!result) {
    result = hasIEPlugin("ShockwaveFlash.ShockwaveFlash");
  }
}

8.3.2 注冊處理程序

8.4 screen 對象

8.5 history 對象

historywindow對象的屬性唇敞,因此每個瀏覽器窗口、每個標簽頁乃至每個框架咒彤,都有自己的history對象與特定的window對象關(guān)聯(lián)疆柔。
使用go()方法可以在用戶的歷史紀錄中任意跳轉(zhuǎn),可以向后也可以向前镶柱。該方法接受一個參數(shù)旷档,表示向后或向前跳轉(zhuǎn)的頁面數(shù)的一個整數(shù)值。負數(shù)表示向后跳轉(zhuǎn)歇拆,正數(shù)相反鞋屈。

//后退一頁
history.go(-1);
//前進一頁
history.go(1);
//前進兩頁
history.go(2);

也可以給go()方法傳遞一個字符串參數(shù),此時瀏覽器會跳轉(zhuǎn)到歷史紀錄中包含該字符串的第一個位置---可能后退查吊,也可能前進谐区。如果歷史紀錄中不包含該字符串,那么這個方法什么也不做逻卖。

//跳轉(zhuǎn)到最近的 wrox.com 頁面
history.go("wrox.com");
//跳轉(zhuǎn)到最近的 nczonline.net 頁面
history.go("nczonline.net");

還可以使用back()forward()來代替go()宋列。

//后退一頁
history.back();
//前進一頁
history.forward();

還有一個length屬性,保存著歷史紀錄的數(shù)量评也。

if (history.length == 0) {
  //這應(yīng)該是用戶打開窗口的第一個頁面
}

8.6 小結(jié)

瀏覽器對象模型以window對象為依托炼杖,表示瀏覽器窗口以及頁面可見區(qū)域灭返。同時,window對象還是 ECMAScript 中的Global對象坤邪,因而所有全局變量和函數(shù)都是它的屬性熙含,且所有原生的構(gòu)造函數(shù)及其他函數(shù)也都存在與它的命名空間下。

  • 在使用框架時艇纺,每個框架都有自己的window對象以及所有原生構(gòu)造函數(shù)及其他函數(shù)的副本怎静。每個框架都保存在frames集合中,可以通過位置或通過名稱來訪問黔衡。
  • 有一些窗口指針蚓聘,可以用來引用其他框架,包括父框架盟劫。
  • top對象始終指向最外圍的框架夜牡,也就是整個瀏覽器窗口。
  • parent對象表示包含當前框架的框架侣签,而self對象則回指window塘装。
  • 使用location對象可以通過編程方式來訪問瀏覽器的導(dǎo)航系統(tǒng)。設(shè)置相應(yīng)的屬性影所,可以逐段或整體性地修改瀏覽器的 URL蹦肴。
  • 調(diào)用replace()方法可以導(dǎo)航到一個新 URL,同時 URL 會替換瀏覽器歷史紀錄中當前顯示的頁面型檀。
  • navigator對象提供了與瀏覽器有關(guān)的信息冗尤。到底提供哪些信息,很大程度上取決于用戶的瀏覽器胀溺;不過裂七,也有一些公共的屬性存在于所有瀏覽器中。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仓坞,一起剝皮案震驚了整個濱河市背零,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌无埃,老刑警劉巖徙瓶,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嫉称,居然都是意外死亡侦镇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門织阅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來壳繁,“玉大人,你說我怎么就攤上這事∧致” “怎么了蒿赢?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長渣触。 經(jīng)常有香客問我羡棵,道長,這世上最難降的妖魔是什么嗅钻? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任皂冰,我火速辦了婚禮,結(jié)果婚禮上养篓,老公的妹妹穿的比我還像新娘灼擂。我一直安慰自己,他們只是感情好觉至,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著睡腿,像睡著了一般语御。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上席怪,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天应闯,我揣著相機與錄音,去河邊找鬼挂捻。 笑死碉纺,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的刻撒。 我是一名探鬼主播骨田,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼声怔!你這毒婦竟也來了态贤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤醋火,失蹤者是張志新(化名)和其女友劉穎悠汽,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芥驳,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡柿冲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了兆旬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片假抄。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出慨亲,到底是詐尸還是另有隱情婚瓜,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布刑棵,位于F島的核電站巴刻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛉签。R本人自食惡果不足惜胡陪,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碍舍。 院中可真熱鬧柠座,春花似錦、人聲如沸片橡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捧书。三九已至吹泡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間经瓷,已是汗流浹背爆哑。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舆吮,地道東北人揭朝。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像色冀,于是被迫代替她去往敵國和親潭袱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容