0%

JS 筆記 - 認識 BOM

JavaScript Note

BOM 是什麼

Browser Object Model 瀏覽器物件模型,簡稱 BOM,是瀏覽器所有功能的核心,與網頁的內容無關。

在早期沒有制定標準規範的時候,各家瀏覽器廠商幾乎各自在自家瀏覽器上實作功能,非常混亂。 直到最近幾年, W3C 把各家瀏覽器都有實作的部分,以及確定已經(或未來會) 加入的功能,統一集合起來納入了 HTML5 的標準中,這也就是我們現在看到的 BOM API 的實作。

BOM 也有人非正式地稱它為 「Level 0 DOM」。 因為它在 DOM level 1 標準前就已存在,而不是真的有文件去規範這些,所以「Level 0 DOM」與「BOM」兩者實際上指的是同一個東西。

簡單來說
BOM,是 JavaScript 與瀏覽器溝通的橋樑,JavaScript 可以透過 BOM 對瀏覽器進行各種操作,包含開啟及關閉視窗、改變視窗大小、計時器、取得位址之類的。

BOM

什麼是 Window

BOM 的核心是 window 物件,而 window 物件提供的特性主要為 documentlocationnavigatorscreenhistory 以及 frames

在瀏覽器裡的 window 物件扮演著兩種角色:

  • ECMAScript 標準裡的「全域物件」 (Global Object)
  • JavaScript 用來與瀏覽器溝通的窗口

可以透過 chrome 開發人員工具中的 console 輸入 window ,得到相關的值,假如我今天想要得到網頁中的 a 連結資訊,就可以這樣輸入:

1
2
var a = 111;
console.log(window.a); //111

另外,window 也是瀏覽器中的對話框,一開始學習 JavaScript,就先學 alert,

1
alert("這裡是一段文字");

但其實其完整的程式碼是這樣寫:

1
window.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 指的可見的瀏覽器範圍,如下圖紅框處:

innerHeight

outerHeight 指的是整個瀏覽器範圍,如下圖:

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


參考資料: