JS學習筆記(五)(BOM)

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

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

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

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

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

  • 所有在全局作用域中聲明的變量、函數(shù)都會變成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集合中,可以通過數(shù)值索引(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中返回的是頁面可見區(qū)域(不包括工具欄)到屏幕左邊和上邊的值

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

  • moveTo()

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

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

<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():

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

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

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

window.open():

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

    • 第一個參數(shù):通常只需傳遞第一個參數(shù)。

    • 第二個參數(shù):

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

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

      3. _parent

      4. _top

      5. _blank

    • 第三個參數(shù):

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

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

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

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

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

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

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

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

    • 代碼:

        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時,就是告訴瀏覽器新建的標簽頁不需要與打開它的標簽頁通信,因此可以在獨立的進程中運行。標簽頁的聯(lián)系一旦切斷,將沒有辦法恢復

彈出窗口屏蔽程序

  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是單線程語言,但它允許通過設置超時值和間歇時間值來調度代碼在特定的時刻執(zhí)行。

  1. 超時調用:setTimeOut()

    • 參數(shù):要執(zhí)行的代碼和以毫秒表示的時間

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

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

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

        clearTimeOut(timeoutId);

  2. 間歇調用:setInterval()

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

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

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

function incrementNumber(){
    num++;
    //如果執(zhí)行次數(shù)達到max,則取消后續(xù)尚未執(zhí)行的調用
    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。一般認為,使用超時調用模擬間歇調用是一種最佳模式。在開發(fā)環(huán)境下,很少使用間歇調用,因為后一個間歇調用可能會在前一個間歇調用結束前啟動。所以最好不要使用間歇調用

<h3 id="8.1.7">8.1.7 系統(tǒng)對話框</h3>

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

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

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

  • 打?。?code>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 查詢字符串參數(shù)</h3>

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

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()方法:

  • 作用:禁用后退按鈕

  • 示例:訪問該網(wǎng)頁的時候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()之后的代碼可能不執(zhí)行,取決于網(wǎng)絡延遲或系統(tǒng)資源等因素,因此最好將reload()放在代碼最后一行

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

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

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

非IE:

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

    • name:插件名字
    • description:插件描述
    • filename:插件文件名
    • length:插件所處理的MIME類型數(shù)量
  • 具體:循環(huán)迭代每個插件并將插件的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類型

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

  • 代碼:

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

因此在所有瀏覽器中檢測時要針對每個插件分別創(chuàng)建函數(shù):

//檢測所有瀏覽器中的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>

用來表現(xiàn)客戶端能力

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

用來保存歷史記錄

  • history.go()方法

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

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

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

  • 在使用框架時,每個框架都有自己的window對象以及所有原生構造函數(shù)和其他函數(shù)的副本。每個框架都保存在frames集合中
  • 有一些窗口指針,可以用來引用其他框架,包括父框架
  • top對象始終指向最外圍的框架
  • parent對象指向包含當前框架的框架
  • self對象回指window
  • location對象可以通過編程方式來訪問瀏覽器的導航系統(tǒng)
  • 調用replace()方法可以導航到一個新的URL并替換歷史記錄種當前顯示的頁面
  • navigator對象提供了與瀏覽器有關的信息
  • screen對象保存著與客戶端顯示器有關的信息
  • history對象保存著歷史記錄,包括后退和前進
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • ECMAScript 是 JavaScript 的核心,但如果要在 Web 中使用 JavaScript,那么 B...
    劼哥stone閱讀 880評論 2 5
  • BOM是瀏覽器對象模型,它提供了很多用于訪問瀏覽器的功能。 window對象 BOM的核心對象是window,它表...
    exialym閱讀 474評論 0 3
  • 昨天吃過早飯,按計劃去一個學校附近踩點。臨走前,孩子一定要他爸爸一起去。 我說:"為什么呀?"孩子說:"沒個男的陪...
    若冰瑤燁閱讀 1,112評論 0 0
  • 人的腦力精力都是有限的,我們不可能像電腦那樣無休無止的工作,還能不感覺到累。因此如何高效工作,把自己那有...
    鴻運當頭168閱讀 284評論 0 2
  • 那年,2009年的暑假,高考結束后,跟姐去淮安的富士康電子廠打工! 到了廠里,才知道,只有午餐免費。帶的錢漸漸沒有...
    簡單木子閱讀 178評論 0 0

友情鏈接更多精彩內容