JS學習筆記(五)(BOM)

<h1 id="8">第8章 BOM</h1>
本章內容主要是

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

<h2 id="8.1">8.1 window對象</h2>

  • BOM的核心對象是window,它表示瀏覽器的一個實例。
  • window對象既是通過JS訪問瀏覽器窗口的一個接口,又是ES規定的Global對象
  • 網頁中定義的熱呢一個對象、變量和函數,都以window作為其Global對象

<h3 id="8.1.1">8.1.1 全局作用域</h3>

  • 所有在全局作用域中聲明的變量、函數都會變成window對象的屬性和方法

  • 定義全局變量和直接在window對象上定義屬性有一點差別:全局變量不能通過delete操作符刪除,而直接在window對象上定義的屬性可以。這是因為使用var語句添加的window屬性有一個名為[[Configurable]]的特性,值被設為false

  • 嘗試訪問未聲明的變量會拋出錯誤,但是通過查詢window對象,可以知道某個可能未聲明的變量是否存在

      //這樣不會有錯誤。值是undefined
      var newValue = window.oldValue;
      //拋出錯誤
      var newValue = oldValue;
    

<h3 id="8.1.2">8.1.2 窗口關系及框架</h3>

  • 如果頁面中包含框架(像frameset這種),則每個框架都有自己的window對象,并且保存在frames集合中。
  • 在frames集合中,可以通過數值索引(0開始,從左到右,從上到下)或者框架名稱來訪問相應的window對象
  • 每個window對象都有一個name屬性,其中包含框架的名稱

top對象:

  • top對象始終指向最高(最外)層的框架,也就是瀏覽器窗口,使用它可以確保在一個框架中正確地訪問另一個框架

window對象:

  • 在一個框架中的window指向的都是自己那個框架,不是最高層的

parent對象:

  • 始終指向當前框架的直接上層框架
  • 在某些情況下,parent有可能等于top;在沒有框架的情況下,parent一定等于top(都是window)

self對象:

  • 始終指向window
  • 引入self只是為了與top和parent對應起來

<h3 id="8.1.3">8.1.3 窗口關系及框架</h3>

跨瀏覽器取得窗口左邊和上邊的位置:

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

這是因為Safari、Opera和Chrome中存在screenLeft和screenTop屬性,而在Firefox中是scrrenX和ScreenY

無法在跨瀏覽器的條件下取得窗口左邊和上邊的精確坐標值,因為在Firefox和Safari中返回的是整個瀏覽器窗口相對于屏幕的坐標值,在IE、Opera和Chrome中返回的是頁面可見區域(不包括工具欄)到屏幕左邊和上邊的值

將窗口精確地移動到一個新位置的方法:
這兩種方法可能會被瀏覽器禁用。且不適用于框架,只對最外層的window對象使用

  • moveTo()

    • 參數:新位置的x和y坐標
  • moveBy()

    • 參數:在水平和垂直方向上移動的像素數

<h3 id="8.1.4">8.1.4 窗口大小</h3>

不同瀏覽器中返回的innerWidth、innerHeight、outerWidth和outerHeight不一樣,因此無法最終確定瀏覽器窗口本身的大小,但可以取得頁面視口的大小

var pageWidth = wimdow.innerWidth,
    pageHeight = window.innerHeight;

if(typeof pageWidth != "number"){
    if(document.compatMode == "CSS1Compat"){//判斷是不是標準模式
        pageWidth = document.documentElement.clientWidth;
        pageHeight = document.documentElement.clientHeight;
    }else{
        pageWidth = document.body.clientWidth;
        pageHeight = document.body.clientHeight;
    }
}

調整瀏覽器窗口大小的兩個方法:
與移動窗口位置的兩個方法類似,也有可能被瀏覽器禁用。同樣不適用于框架,只能對最外層的window對象使用

  • resizeTo():

    • 參數:瀏覽器窗口的新寬度和新高度
  • resizeBy():

    • 參數:新窗口與原窗口的寬度和高度之差

<h3 id="8.1.5">8.1.5 導航和打開窗口</h3>

window.open():

  • 參數:要加載的URL、窗口目標、一個特性字符串、一個表示新頁面是否取代瀏覽器歷史記錄中當前加載頁面的布爾值

    • 第一個參數:通常只需傳遞第一個參數。

    • 第二個參數:

      1. 該參數是已有窗口或框架的名稱

        • 在指定的窗口或框架中加載指定URL
        • 代碼:
          //等同于<a target="topFrame"></a>
          window.open("http://www.baidu.com/","topFrame");
        • 如果沒有窗口或框架的名稱是topFrame,就會創建一個新窗口并將其命名為topFrame
      2. _self

      3. _parent

      4. _top

      5. _blank

    • 第三個參數:

      • 如果第二個參數并不是已經存在的窗口或框架,那么就會根據在第三個參數位置上傳入的字符串創建一個新窗口或新標簽頁。如果沒有第三個參數,就會打開一個帶有全部默認設置的新瀏覽器窗口

      • 在不打開新窗口的情況下,會忽略第三個參數

      • 是一個用逗號分隔的設置字符串,表示新窗口的特性

      • 整個特性字符串中不能有空格,比如:

        window.open("http://www.baidu.com/","topFrame","height=400,width=400");

    • 第四個參數:只在不打開新窗口的情況下使用

  • 返回:一個指向新窗口的引用

    • 用途:可以針對 通過window.open()創建的窗口 調整大小或移動位置

    • 代碼:

        var wroxWin = window.open("http://www.baidu.com/","wroxWindow","height=400,width=400");
        wroxWin.resizeTo(500,500);
        wroxWin.moveTo(100,100)
      
    • wroxWin.close()還可以關閉這個新打開的窗口

    • 要注意的是對于瀏覽器的主窗口,如果沒有得到用戶允許是不能關閉的(除了彈出窗口可以調用top.close()關閉)

  • opener屬性

    • 定義于新窗口的最外層window對象(top)中,指向原始窗口(調用window.open()的窗口或框架)
    • 當把opener屬性設置為null時,就是告訴瀏覽器新建的標簽頁不需要與打開它的標簽頁通信,因此可以在獨立的進程中運行。標簽頁的聯系一旦切斷,將沒有辦法恢復

彈出窗口屏蔽程序

  1. 內置的屏蔽程序阻止彈出窗口:window.open()返回null

  2. 擴展或其他程序阻止彈出窗口:拋出一個錯誤
    因此準確檢測出彈出窗口是否被屏蔽的代碼如下:

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

<h3 id="8.1.6">8.1.6 間歇調用和超時調用</h3>

JS是單線程語言,但它允許通過設置超時值和間歇時間值來調度代碼在特定的時刻執行。

  1. 超時調用:setTimeOut()

    • 參數:要執行的代碼和以毫秒表示的時間

      • 第一個參數:可以是一個包含JS代碼的字符串(同eval()函數里的字符串),也可以是一個函數
      • 不建議以字符串作為第一個參數。因為可能導致性能缺失
      • 第二個參數:是一個表示等待多長時間的毫秒數。JS是一個單線程的解釋器,有一個JS任務隊列,這些任務按照將它們添加到隊列 的順序執行。也就是說這個參數只是指定多長時間后把任務添加到隊列。但不一定會立即執行(前面可能還有任務)。
    • 返回:一個數值ID,表示超時調用

      • 這個超時調用ID是計劃執行代碼的唯一標識符

      • 只要指定的時間尚未過去,就可以取消尚未執行的超時調用計劃:傳入ID

        clearTimeOut(timeoutId);

  2. 間歇調用:setInterval()

    • 參數:(與setTimeOut()相同)要執行的代碼和以毫秒表示的時間
    • 區別:按照指定的時間間隔重復執行代碼,直到間歇調用被取消或者頁面被卸載
    • 返回:間歇調用ID
    • 取消:clearInterval(Id)

一個常見的使用間歇調用的例子

var num =0;
var max = 10;
var intervalId = null;

function incrementNumber(){
    num++;
    //如果執行次數達到max,則取消后續尚未執行的調用
    if(num == max){
        clearInterval(intervalId);
        alert("Done");
    }
}

intervalId = setInterval(incrementNumber,500);

與以上代碼相同功能的超時調用:

var num = 0;
var max = 10;
function incrementMunber(){
    num++;
    if(num < max){
        setTimeout(incrementNumber,500);
    }else{
        alert("Done");
    }
}
setTimeout(incrementNumber,500);

比較上面兩段代碼,可以看出超時調用不需要跟蹤超時調用ID。一般認為,使用超時調用模擬間歇調用是一種最佳模式。在開發環境下,很少使用間歇調用,因為后一個間歇調用可能會在前一個間歇調用結束前啟動。所以最好不要使用間歇調用

<h3 id="8.1.7">8.1.7 系統對話框</h3>

以下三個不涉及HTML、CSS、JS

  • alert():警告
  • confirm():確認
  • prompt():提示
    • 參數:要顯示給用戶的文本提示和文本輸入域(可以是"")
    • 返回:單擊OK則返回文本輸入域的值,單擊cancel或通過其他方式關閉對話框則返回null

以下兩個可以通過JS打開的對話框:查找和打印。這兩個對話框都是異步顯示的,能夠將控制權立即交還給腳本。與用戶通過瀏覽器菜單的查找和打印命令打開的對話框相同

  • 打印:window.print();
  • 查找:window.find();

<h2 id="8.2">8.2 location對象</h2>

location提供了與當前窗口中加載的文檔有關的信息,還提供了一些導航功能。
location既是window對象的屬性,也是document對象的屬性。
location將URL解析為獨立的片段

<h3 id="8.2.1">8.2.1 查詢字符串參數</h3>

以下函數解析查詢字符串,然后返回包含所有參數的一個對象:

function getQueryStringArgs(){
    var qs = location.search.length > 0 ? location.search.substring(1) : "";
    var args = {};
    var items = qs.length > 0 ? qs.split("&") : [];
    var item = null;
    var name = null;
    var value = null;
    for(var i = 0; i<items.length; i++){
        item = items[i].split("=");
        name = decodeURIComponent(item[0]);
        value = decodeURIComponent(item[1]);
        if(name.length){
            args[name] = value;
        }
    }
    return args;

}

<h3 id="8.2.2">8.2.2 位置操作</h3>

以下三種方法本質上都是調用assign()方法,location.href比較常用

  • location.assign(URL);
  • window.location = URL;
  • location.href = URL;

通過改變location對象的其他屬性值來改變當前加載的頁面:

//假設初始URL為http://www.wrox.com/WileyCDA/

//http://www.wrox.com/WileyCDA/#section1
location.hash = "#section1";

//http://www.wrox.com/WileyCDA/?q=javascript
location.search = "?q=javascript";

//http://www.yahoo.com/WileyCDA/
location.hostname = "www.yahoo.com";

//http://www.wrox.com/mydir/
location.pathname = "mydir";

//http://www.wrox.com:8080/WileyCDA/
location.port = 8080;

每次修改location的屬性(除hash),頁面都會以新URL重新加載

replace()方法:

  • 作用:禁用后退按鈕

  • 示例:訪問該網頁的時候1s后導航到百度,并且后退按鈕被禁用

      <!DOCTYPE html>
      <html>
      <head lang="en">
      <meta charset="UTF-8">
      <title></title>
      </head>
      <body>
      <script type="text/javascript">
          setTimeout(function () {
              location.replace("http://www.baidu.com/");
          },1000);
      </script>
      </body>
      </html>
    

reload()方法:

  • location.reload();//重新加載(有可能從緩存中加載)
  • location.reload(true);//重新加載(從服務器重新加載)
  • 位于reload()之后的代碼可能不執行,取決于網絡延遲或系統資源等因素,因此最好將reload()放在代碼最后一行

<h2 id="8.3">8.3 navigator對象</h2>

navigator對象的屬性通常用于檢測顯示網頁的瀏覽器類型

<h3 id="8.3.1">8.3.1 檢測插件</h3>

非IE:

  • 方法:用plungins數組,plungins的每一項包含下列屬性:

    • name:插件名字
    • description:插件描述
    • filename:插件文件名
    • length:插件所處理的MIME類型數量
  • 具體:循環迭代每個插件并將插件的name與給定的名字比較

  • 代碼:

      function hasPlungin(name){
          name = name.toLowerCase();
          for(var i=0;i<navigator.plungins.length;i++){
              if(navagator.plungins[i].name.toLoowerCase().indexOf(name)>-1){
                  return true;
              }
          }
          return false;
      }
    

IE:

  • 方法:使用專有的ActiveXObject類型

  • 具體:傳入的參數是一個COM標識符,通過嘗試創建一個特定插件的實例來確定有沒有插件

  • 代碼:

      function hasIEPlungins(name){
          try{
              new ActiveXObject(name);
              return true;
          }catch (ex){
              return false;
          }
      }
    

因此在所有瀏覽器中檢測時要針對每個插件分別創建函數:

//檢測所有瀏覽器中的Flash
function hasFlash(){
    var result = hasPlungin("Flash");
    if(!result){
        result = hasIEPlungin("ShockwaveFlash.ShockwaveFlash");
    }
    return result;
}

<h3 id="8.3.2">8.3.2 注冊處理程序</h3>

<h2 id="8.4">8.4 screen對象</h2>

用來表現客戶端能力

<h2 id="8.5">8.5 history對象</h2>

用來保存歷史記錄

  • history.go()方法

    • 參數:整數值(負數向后跳轉,相當于后退)或字符串
    • 當輸入字符串時,會跳到最近的包含這個字符串的頁面
    • history.back():后退一頁
    • history.forward():前進一頁
  • length屬性

    • 檢測當前頁面是不是用戶打開的第一個頁面

<h2 id="8.6">8.6 小結</h2>

  • 在使用框架時,每個框架都有自己的window對象以及所有原生構造函數和其他函數的副本。每個框架都保存在frames集合中
  • 有一些窗口指針,可以用來引用其他框架,包括父框架
  • top對象始終指向最外圍的框架
  • parent對象指向包含當前框架的框架
  • self對象回指window
  • location對象可以通過編程方式來訪問瀏覽器的導航系統
  • 調用replace()方法可以導航到一個新的URL并替換歷史記錄種當前顯示的頁面
  • navigator對象提供了與瀏覽器有關的信息
  • screen對象保存著與客戶端顯示器有關的信息
  • history對象保存著歷史記錄,包括后退和前進
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容