BOM 是什麼
Browser Object Model 瀏覽器物件模型,簡稱 BOM,是瀏覽器所有功能的核心,與網頁的內容無關。
在早期沒有制定標準規範的時候,各家瀏覽器廠商幾乎各自在自家瀏覽器上實作功能,非常混亂。 直到最近幾年, W3C 把各家瀏覽器都有實作的部分,以及確定已經(或未來會) 加入的功能,統一集合起來納入了 HTML5 的標準中,這也就是我們現在看到的 BOM API 的實作。
BOM 也有人非正式地稱它為 「Level 0 DOM」。 因為它在 DOM level 1 標準前就已存在,而不是真的有文件去規範這些,所以「Level 0 DOM」與「BOM」兩者實際上指的是同一個東西。
簡單來說
BOM,是 JavaScript 與瀏覽器溝通的橋樑,JavaScript 可以透過 BOM 對瀏覽器進行各種操作,包含開啟及關閉視窗、改變視窗大小、計時器、取得位址之類的。
什麼是 Window
BOM 的核心是 window
物件,而 window
物件提供的特性主要為 document
、location
、navigator
、screen
、history
以及 frames
。
在瀏覽器裡的 window
物件扮演著兩種角色:
- ECMAScript 標準裡的「全域物件」 (Global Object)
- JavaScript 用來與瀏覽器溝通的窗口
可以透過 chrome 開發人員工具中的 console
輸入 window
,得到相關的值,假如我今天想要得到網頁中的 a
連結資訊,就可以這樣輸入:
1 2
| var a = 111; console.log(window.a);
|
另外,window 也是瀏覽器中的對話框,一開始學習 JavaScript,就先學 alert,
但其實其完整的程式碼是這樣寫:
window
一般都省略不寫,這就是瀏覽器環境的 BOM 提供給 JavaScript 控制的功能之一。
常用的 window 功能
當前瀏覽器尺寸 screen
當輸入 window.screen
的時候,會得知當前瀏覽器尺寸。
1 2 3 4 5 6 7 8 9 10 11
| Screen {availWidth: 1920, availHeight: 1040, width: 1920, height: 1080, colorDepth: 24, …} availWidth: 1920 availHeight: 1040 width: 1920 height: 1080 colorDepth: 24 pixelDepth: 24 availLeft: 0 availTop: 0 orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null} __proto__: Screen
|
當前瀏覽的網址
當輸入 window.location
的話,可以找到 href
的資訊,就是當前網址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| Location {href: "https://tw.yahoo.com/", ancestorOrigins: DOMStringList, origin: "https://tw.yahoo.com", protocol: "https:", host: "tw.yahoo.com", …} ancestorOrigins: DOMStringList {length: 0} origin: "https://tw.yahoo.com" protocol: "https:" host: "tw.yahoo.com" hostname: "tw.yahoo.com" port: "" pathname: "/" search: "" hash: "" href: "https://tw.yahoo.com/" assign: ƒ assign() reload: ƒ reload() toString: ƒ toString() replace: ƒ replace() valueOf: ƒ valueOf() Symbol(Symbol.toPrimitive): undefined __proto__: Location
|
當前瀏覽器相關資訊
輸入 window.navigator 的話,會得到下方資訊, onload
就是上網狀態, true
就是上網中,false
就是離線:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| Navigator {vendorSub: "", productSub: "20030107", vendor: "Google Inc.", maxTouchPoints: 0, hardwareConcurrency: 8, …} vendorSub: "" productSub: "20030107" vendor: "Google Inc." maxTouchPoints: 0 hardwareConcurrency: 8 cookieEnabled: true appCodeName: "Mozilla" appName: "Netscape" appVersion: "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36" platform: "Win32" product: "Gecko" userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36" language: "zh-TW" languages: (5) ["zh-TW", "zh", "en-US", "en", "ia"] onLine: true doNotTrack: null geolocation: Geolocation {} mediaCapabilities: MediaCapabilities {} connection: NetworkInformation {onchange: null, effectiveType: "4g", rtt: 0, downlink: 10, saveData: false} plugins: PluginArray {0: Plugin, 1: Plugin, 2: Plugin, Chrome PDF Plugin: Plugin, Chrome PDF Viewer: Plugin, Native Client: Plugin, length: 3} mimeTypes: MimeTypeArray {0: MimeType, 1: MimeType, 2: MimeType, 3: MimeType, application/pdf: MimeType, application/x-google-chrome-pdf: MimeType, application/x-nacl: MimeType, application/x-pnacl: MimeType, length: 4} webkitTemporaryStorage: DeprecatedStorageQuota {} webkitPersistentStorage: DeprecatedStorageQuota {} userActivation: UserActivation {hasBeenActive: true, isActive: true} mediaSession: MediaSession {metadata: null, playbackState: "none"} permissions: Permissions {} deviceMemory: 8 clipboard: Clipboard {} credentials: CredentialsContainer {} keyboard: Keyboard {} locks: LockManager {} mediaDevices: MediaDevices {ondevicechange: null} serviceWorker: ServiceWorkerContainer {ready: Promise, controller: null, oncontrollerchange: null, onmessage: null, onmessageerror: null} storage: StorageManager {} presentation: Presentation {receiver: null, defaultRequest: null} bluetooth: Bluetooth {} usb: USB {onconnect: null, ondisconnect: null} xr: XR {ondevicechange: null} __proto__: Navigator
|
上一頁與下一頁的功能
使用 history
來製作上一頁與下一頁的語法,先在 console
輸入 history,會看到其中這兩個語法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| History {length: 1, scrollRestoration: "auto", state: null} length: 1 scrollRestoration: "auto" state: null __proto__: History length: (...) scrollRestoration: (...) state: (...) go: ƒ go() back: ƒ back() forward: ƒ forward() pushState: ƒ pushState() replaceState: ƒ replaceState() constructor: ƒ History() Symbol(Symbol.toStringTag): "History" get length: ƒ length() get scrollRestoration: ƒ scrollRestoration() set scrollRestoration: ƒ scrollRestoration() get state: ƒ state() __proto__: Object
|
做兩個按鈕,點擊後可以進行上一頁與下一頁,
HTML
1 2 3 4 5
| <div class="aLink"> <a href="https://tw.yahoo.com/">Yahoo!</a> </div> <input type="button" id="backBtn" value="上一頁" /> <input type="button" id="forwardBtn" value="下一頁" />
|
綁定兩個 id
後,寫入監聽事件,
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var back = document.getElementById("backBtn"); var foward = document.getElementById("forwardBtn");
function back() { window.history.back(); } back.addEventListener("click", back, false);
function forward() { window.history.forward(); } foward.addEventListener("click", forward, false);
|
在讀取到新的頁面後,就可以進行上一頁與下一頁囉!!
codepen: https://codepen.io/hnzxewqw/pen/mdJMrdN
程式碼僅供對照,無法實現跳轉後功能。
列印功能
寫一個列印按鈕,並綁定 id
寫入列印語法:
html
1
| <input type="button" id="print" value="列印" />
|
JavaScript
1 2 3
| document.getElementById("print").onclick = function () { window.print(); };
|
codepen: https://codepen.io/hnzxewqw/pen/bGdrwLq
innerHeight, outerHeight 動態擷取瀏覽器高度
innerHeight 指的可見的瀏覽器範圍,如下圖紅框處:
outerHeight 指的是整個瀏覽器範圍,如下圖:
如果要讓網頁圖片,不管是什麼尺寸的瀏覽器,都可以滿版呈現,可以這樣寫:
html
1 2 3 4
| <div class="pic"></div> <div class="section2">section2</div> <p>lorem150</p> //文字長度部分用數字代替,避免版面過長
|
綁定 .pic
後,動態修改 CSS 的高度樣式(覆蓋原本的數值),讓瀏覽器的 innerHeight
給予當前數值,並且後面要加上單位 'px'
,這樣圖片就會變成滿版了。
JavaScript
1
| document.querySelector(".pic").style.height = window.innerHeight + "px";
|
如果任意改變瀏覽器視窗大小,也要讓圖片的高度數值跟著改變,可以在上方程式碼下,再加上這一段,在 onresize
的時候,會自動改變 CSS 內的 innerHeight
的數值。
1 2 3
| window.onresize = function () { document.querySelector(".pic").style.height = window.innerHeight + "px"; };
|
codepen: https://codepen.io/hnzxewqw/pen/BaNdvrL
參考資料: