Minghsin University of Science and Technology
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

1

Local AI

--

Uedu Code

--

明新科大 AQI 70 24°C PM2.5 19
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 18

window 與 document

window 的方法、location、history 與 document 屬性
Interaction實作 15 minute(s)

Learning Objectives

  • 說明 window 是瀏覽器的全域物件:全域的 var 變數與函式宣告會成為 window 的屬性,let、const 不會
  • 使用 alert、confirm、prompt 對話框並說明回傳值,認識 open、close 等視窗方法的限制
  • 用 location、history、navigator、screen 取得瀏覽器與網址的資訊,並用 URL、URLSearchParams 解析網址
  • 使用 document 的常用屬性:title、URL、forms、links、images,並說明為什麼不要用 document.write

window:瀏覽器分頁本身

前幾課一直在用 document,它其實是 window.document。window 物件代表載入網頁的那個瀏覽器視窗(分頁), 是瀏覽器裡 JavaScript 的全域物件,可以把它的成員分成三類:

類別 例子 內容
環境物件 location、history、navigator、screen 網址、瀏覽紀錄、瀏覽器、螢幕等外部環境的資訊
JavaScript 物件 Math、JSON、console,以及你在最外層宣告的變數與函式 語言內建的物件與全域的名稱
Document 物件 document 目前載入的網頁(DOM 樹)

因為 window 是全域物件,使用它的成員時可以省略 window.:alert('嗨') 就是 window.alert('嗨'), innerWidth 就是 window.innerWidth。

全域變數與 window

在瀏覽器裡,寫在最外層的宣告與 window 的關係如下:

寫法 是全域變數嗎 會變成 window 的屬性嗎
var siteName = 'Uedu' 是 會:window.siteName 是 'Uedu'
function hello() {} 是 會:window.hello 就是這個函式
let version = 3、const MAX = 10 是 不會:window.version 是 undefined
count = 1(沒有宣告就指定) 不是宣告 一般模式下會自動變成 window 的屬性;嚴格模式('use strict')下直接出現 ReferenceError

全域的名稱越多,越容易和別人的程式(或瀏覽器新增的屬性)撞名,造成難以察覺的錯誤。實務上盡量少用全域變數, 宣告一律用 let、const,變數放進函式或模組裡。

對話框是 window 最常用的方法:

方法 畫面 回傳
alert('訊息') 訊息+「確定」 undefined
confirm('確定刪除?') 訊息+「確定」「取消」 按確定是 true,按取消是 false
prompt('你的名字?', '預設值') 訊息+輸入框 輸入的內容(一定是字串);按取消是 null

對話框會讓整個頁面停住,直到使用者按下按鈕,所以正式的網站多半改用頁面裡的對話框元件(Uedu 用的是 SweetAlert2)。 這一課的沙箱不會真的跳出視窗:confirm 一律當作按了「確定」,prompt 回傳你寫的預設值,內容都顯示在主控台。

互動練習:全域物件與對話框

範例先呼叫了 alert 與 confirm,看主控台顯示的內容與回傳值。依任務在 JavaScript 分頁最後面寫程式,按「執行」。

想一想:window 與對話框

1.

瀏覽器的網頁最外層寫了 var a = 1; 與 let b = 2;,window.a 與 window.b 分別是什麼?

2.

下面的程式會印出什麼?(第一行模擬使用者在 prompt 輸入 5:prompt 回傳的是字串)

const n = '5';
console.log(n + 1);
3.

使用者在 prompt 的對話框按了「取消」,prompt 回傳什麼?

第 1 次作答

開啟與控制視窗

方法 作用
const w = window.open(網址, 名稱, 設定) 開啟新視窗或分頁,回傳新視窗的 window 物件(被擋下時是 null)
w.close() 關閉視窗;一般只能關閉用 window.open 開出來的視窗
focus()/blur() 讓視窗取得、失去焦點
moveTo(x, y)/moveBy(dx, dy) 把視窗移到某個位置、移動一段距離
resizeTo(寬, 高)/resizeBy(dw, dh) 調整視窗大小

window.open 的第三個參數是一串設定,例如 'width=500,height=500,left=100,top=100'。

這些方法在現在的瀏覽器裡都受到限制:

  • 瀏覽器會擋下不是由使用者操作觸發的彈出視窗,window.open 最好寫在按鈕的點擊事件裡。
  • resizeTo 這類方法只對用 window.open 開出來的視窗有效,不能調整使用者自己開的分頁,在手機上可能完全沒有作用。

所以這些方法看得懂即可,這一課的沙箱也不允許開新視窗。

location、history、navigator 與 screen

location:目前網頁的網址。以 https://uedu.tw:8443/codelab/javascript/j18-window?tab=js#recap 為例:

屬性 值
location.href 完整網址;指定新值就會前往該網址
location.protocol 'https:'
location.hostname 'uedu.tw'
location.port '8443'(使用預設連接埠時是空字串)
location.host 'uedu.tw:8443'(主機名稱加連接埠)
location.pathname '/codelab/javascript/j18-window'
location.search '?tab=js'(查詢字串,包含問號)
location.hash '#recap'(包含 #)
location.origin 'https://uedu.tw:8443'(通訊協定+主機名稱+連接埠)

方法:location.assign(網址) 前往新網址(與設定 href 相同)、location.replace(網址) 前往但不留下上一頁紀錄、location.reload() 重新載入。

history:這個分頁的瀏覽紀錄。history.back() 上一頁、history.forward() 下一頁、history.go(-2) 往回兩頁、history.length 紀錄筆數。 基於隱私,程式只能前後移動,讀不到使用者看過哪些網址。

navigator:瀏覽器的資訊,例如 navigator.language(介面語言,如 'zh-TW')、navigator.onLine(是否連上網路)、 navigator.userAgent(瀏覽器識別字串,可以偽造,不適合拿來判斷瀏覽器種類)。

screen:使用者螢幕的資訊,例如 screen.width、screen.height。網頁本身可以使用的區域則是 window.innerWidth、window.innerHeight。

這一課的沙箱網頁網址是 about:srcdoc,沒有主機名稱與路徑,示範不了 location。 location 的屬性名稱和 JavaScript 的 URL 物件相同,下面改用 new URL(網址) 拆解任意網址。

用 URL 物件拆解網址

URL 物件的各個部分在右邊顯示為空的大括號(它們是讀取時才計算的屬性),所以範例把每個部分存進變數。一步一步播放,比較 hostname 與 host、port 的值,以及最後一個網址為什麼沒有連接埠。

讀取查詢字串:URLSearchParams

網址問號後面的 ?q=closure&page=2 叫做查詢字串(query string),常用來把搜尋關鍵字、頁碼傳給網頁。 用字串的 split 自己拆很容易出錯(例如中文與空白會被編碼成 %E4%B8%AD),請用 URLSearchParams:

const params = new URLSearchParams(location.search);   // 在網頁裡讀目前網址的查詢字串
const params2 = new URL(某個網址).searchParams;         // 或從 URL 物件取得
方法 作用
params.get('page') 取得值(一律是字串);沒有這個參數回傳 null
params.getAll('tag') 同名參數出現好幾次時,取得全部的值(陣列)
params.has('sort') 有沒有這個參數
params.set('page', '3')/params.delete('tag') 修改、刪除參數
for (const [key, value] of params) 逐一取得每個參數

讀取與修改查詢字串

注意第 7 行印出的 typeof page:查詢字串裡的數字讀出來是字串,計算前要先轉成數字。第 19、20 行修改參數之後,url.search 也跟著改變。

想一想:網址與查詢字串

1.

下面的程式會印出什麼?

const u = new URL('https://shop.example.com/list?page=2#top');
console.log(u.search, u.hash);
2.

下面的程式會印出什麼?

const u = new URL('http://localhost:8080/app');
console.log(u.host);
3.

下面的程式會印出什麼?

const p = new URLSearchParams('?page=2&size=10');
console.log(p.get('page') + 1);
4.

在網頁裡執行 location.href = 'https://uedu.tw/codelab' 會發生什麼事?

第 1 次作答

實作:從網址算出金額

購物網站把商品、數量與單價放在查詢字串裡。請用 searchParams 讀出 item、qty、price,印出「pen x 3 = 75」這樣的一行(記得數量與單價要先轉成數字再相乘)。

你的輸出
預期輸出

document 的常用屬性

瀏覽器讀入網頁時,依內容建立 DOM,document 就是它的根。除了前幾課的 getElementById、querySelector,document 還有這些常用屬性:

屬性 內容
document.title 網頁標題(<title> 的文字),可以讀也可以改
document.URL 網頁的完整網址(唯讀)
document.forms 頁面上所有的 <form>(HTMLCollection)
document.links 所有有 href 的 <a> 與 <area>
document.images 所有的 <img>
document.getElementsByName('email') 所有 name 是 email 的元素

投影片還介紹了 document.anchors,它只收錄有 name 屬性的 <a>,已經被列為不建議使用的功能。

不要用 document.write。它把字串直接寫進正在載入的文件;如果在網頁載入完成之後才呼叫(例如寫在按鈕的事件裡), 它會先清掉整份文件再重寫,整個頁面就不見了。要加入內容,請用前幾課的 createElement、append 或 textContent。

互動練習:document 的屬性

頁面上有三個連結與一個表單。依任務修改 JavaScript,按「執行」,看主控台的結果。

重點精華回顧

  • window 是瀏覽器的全域物件,使用它的成員時可以省略 window.;最外層的 var 變數與函式宣告會變成 window 的屬性,let、const 不會。
  • 對話框:alert 回傳 undefined、confirm 回傳 true/false、prompt 回傳字串或 null(按取消)。
  • open、close、moveTo、resizeTo 受到瀏覽器限制:彈出視窗要由使用者操作觸發,調整大小只對程式開出來的視窗有效。
  • location 存放目前網址(href、hostname、pathname、search、hash…),指定 href 會前往新網址;history 前後移動;navigator 是瀏覽器資訊;screen 是螢幕資訊。
  • 用 new URL(網址) 拆解網址,用 URLSearchParams 讀取查詢字串;讀出的值一律是字串。
  • document 的常用屬性:title、URL、forms、links、images;不要使用 document.write。
這一課完成了!
Next lesson:事件處理
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。