window對象
ECMAScript是JavaScript的核心,但是如果要在web中使用javascript,那麼BOM(浏覽器對象模型)才是真正的核心。BOM提供了很多對象,用於訪問浏覽器的功能,這些功能與任何網頁內容無關。
window對象:BOM的核心對象是window,它表示浏覽器的一個實例。在浏覽器中,window對象有雙重角色,它既是通過javascript訪問浏覽器窗口的一個接口,又是ECMAScript規定的Global對象。
因此,所有全局作用域中聲明的變量、函數都會變成window對象的屬性和方法。
<script type="text/javascript"> var age=26;//這裡定義的全局變量和全局函數被自動歸在了window對象名下 function sayAge(){ console.log(this.age); } console.log(window.age);//26 sayAge();//26 相當於window.sayAge() window.sayAge();//26 //全局變量和在window對象上直接定義屬性的唯一區別:全局變量不能夠通過delete操作符刪除,而直接在window對象上定義的屬性可以 window.color='red'; delete window.age; delete window.color; console.log(window.age);//26 console.log(window.color);//undefined </script>
<script type="text/javascript"> /* 還要注意:嘗試訪問未聲明的變量會拋出錯誤,但是通過查詢window對象,可以知道某個可能未經聲明的變量是否存在 */ //這會拋出錯誤,因為oldValue未定義 var newValue=oldValue; //這不會拋出錯誤,因為是一次屬性查詢 var newValue=window.oldValue; </script>
窗口關系和框架
如果頁面中包含框架,則每個框架都擁有自己的window對象,並且保存在frames集合中。在frames集合中,可以通過數值索引(從0開始,從左到右,從上到下)或者框架名稱來訪問相應的window對象。每個window對象都有一個name屬性,其中包含著框架的名稱。
可以通過window.frames[0]或者window.frames[“topFrame”]來引用上方的框架。不過,最好使用top,而不是window來引用這些框架。因為,top對象始終指向最高(最外)層的框架,也就是浏覽器窗口。使用它可以確保在一個框架中正確地訪問另一個框架。因為對於一個在框架中編寫的任何代碼來說,其中的window對象指向的都是那個框架的特定實例,而不是最高層的框架。
與top相對的另一個window對象是parent。parent對象始終指向當前框架的直接上層框架。
與框架有關的最後一個對象是self,它始終指向window。self和window對象可以互換使用。
在使用框架的情況下,浏覽器中會存在多個Global對象。在每個框架中定義的全局變量會自動成為框架中window對象的屬性。由於每個window對象都包含原生類型的構造函數,因此每個框架都有一套自己的構造函數,這些構造函數一一對應,但並不相等。
location對象
location對象是一個很特別的對象,因為它既是window對象的屬性,也是document對象的屬性。window.location和document.location引用的是同一個對象。
location對象的屬性:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>查詢字符串參數</title> </head> <body> <script type="text/javascript"> function getQueryStringArgs(){ //取得查詢字符串並去掉開頭的問號 var qs = (location.search.length > 0 ? location.search.substring(1) : ""), //保存數據對象 args = {}, //取得每一項 items = qs.length ? qs.split("&") : [], item = null, name = null, value = null, //在for循環中使用 i = 0, len = items.length; //逐個將每一項添加到args對象中 for (i=0; i < len; i++){ item = items[i].split("="); //decodeURIComponent用來解碼name和value,因為查詢字符串應該是被編碼過的 name = decodeURIComponent(item[0]); value = decodeURIComponent(item[1]); if (name.length){ args[name] = value; } } return args; } //假設查詢字符串是: ?q=javascript&num=10 var args = getQueryStringArgs(); alert(args["q"]); //"javascript" alert(args["num"]); //"10" //這樣一來,每個查詢字符串參數都成了返回對象的屬性,極大地方便了對每個參數的訪問 </script> </body> </html>
使用location對象可以通過很多方式來改變浏覽器的位置。
其中,最常用的方式是:使用assign()方法並為其傳遞一個URL
location.assign(“http://www.jb51.net“)
這樣就可以立即打開新的URL並在浏覽器的歷史記錄中生成一條記錄。
同樣的,將location.href和window.location設置為一個URL值,也會以該值調用assign()方法。
location.href=”http://www.jb51.net”;
window.location=”http://www.jb51.net”;
這兩種方式的效果和顯示調用assign()方法效果完全一樣
此外,通過修改location對象的其他屬性也可以改變當前加載的頁面。
每次修改location的屬性(hash除外),頁面都會以新的URL重新加載。修改hash的值會在浏覽器的歷史記錄中生成一條新的記錄
在url:http://a.com#helloword中的'#helloworld'就是location.hash,改變hash並不會導致頁面刷新,所以可以利用hash值來進行數據傳遞,當然數據容量是有限的。
當通過上述任何一種方法修改URL之後,浏覽器的歷史記錄中就會生成一條新紀錄,因此通過點擊”後退”按鈕都會導航到前一個頁面。
我們可以使用replace()方法來禁用這種行為。該方法只接受一個參數,即要導航到的URL;結果雖然會導致浏覽器位置改變,但不會在歷史記錄中生成新紀錄。在調用replace()方法後,用戶不能回到前一個頁面。
這個頁面加載到浏覽器中後,浏覽器就會在1秒鐘後重新定向到www.jb51.net。然後,'後退'按鈕將處於禁用狀態,如果重新輸入完整的URL,則無法返回示例頁面。
<script type="text/javascript"> setTimeout(function () { location.replace("http://www.jb51.net/"); }, 1000); </script>
reload()方法,其作用是重新加載當前顯示的頁面。如果調用reload()方法時不傳遞任何參數,頁面就會以最有效的方式重新加載。也就是說,如果頁面自上次請求以來並沒有改變過,頁面就會從浏覽器緩存中重新加載。如果要強制從服務器重新加載,需要給該方法傳遞參數true。
location.reload();//重新加載(有可能從緩存中加載)
location.reload(true);//重新加載(從服務器重新加載)
超時調用和間歇調用
javascript是單線程語言,但允許通過設置超時值和間歇值來設定代碼在特定時刻執行
超時調用:是在指定的時間過後執行代碼
間歇調用:每隔指定的時間就執行一次代碼
超時調用:需要使用window對象的setTimeout()方法,接收兩個參數:要執行的代碼和以毫秒表示的時間。
第二個參數是一個表示等待多長時間的毫秒數,但經過該時間後指定的代碼不一定執行。因為,javascript是一個單線程的解釋器,因此一定時間內只能執行一段代碼。第二個參數表示再過多長時間把當前任務添加到隊列中。如果隊列是空的,則代碼會立刻執行,否則就要等待前面的代碼執行完了以後再執行。
調用setTimeout()後,該方法會返回一個數值ID,表示超時調用。要取消未執行的超時調用計劃,可以調用clearTimeout()方法並將相應的超時調用ID作為參數傳遞給它即可。
間歇調用:使用setInterval()方法
與超時調用類似,只不過它會按照指定的時間間隔重復執行代碼,直到間歇調用被取消或者頁面被卸載。它接收的參數與setTimeout()方法一樣
Demo1
<script type="text/javascript"> //設置超時調用 var timeoutId = setTimeout(function() { alert("Hello world!"); }, 1000); //取消超時調用 clearTimeout(timeoutId); </script>
Demo2
<script type="text/javascript"> /* 使用間歇調用實現 */ var num = 0; var max = 10; var intervalId = null; function incrementNumber() { num++; if (num == max) { clearInterval(intervalId); alert("Done"); } } intervalId = setInterval(incrementNumber, 500); </script>
Demo3
<script type="text/javascript"> /* 使用超時調用來實現 */ var num = 0; var max = 100; function incrementNumber() { num++; if (num < max) { setTimeout(incrementNumber, 500); } else { alert("Done"); } } setTimeout(incrementNumber, 500); </script>
在使用超時調用時,沒有必要跟蹤超時調用ID,因為每次執行代碼之後,如果不再設置另一次超時調用,調用就會自動停止。一般認為,使用超時調用來模擬間歇調用是一種最佳模式。間歇調用一般較少使用,因為後一個間歇調用可能會在前一個間歇調用結束之前啟動。
系統對話框
alert()、confirm()和prompt()
<script type="text/javascript"> alert("Hello world!"); </script> <script type="text/javascript"> /* 判斷用戶點擊了OK還是Cancel,可以檢查confirm()方法返回的布爾值:true表示單擊了OK,false表示單擊了Cancel或單擊了右上角的X按鈕。 */ if (confirm("Are you sure?")) { alert("I'm so glad you're sure! "); } else { alert("I'm sorry to hear you're not sure. "); } </script> <script type="text/javascript"> /* prompt()方法用來生成一個"提示"框,用於提示用戶輸入一些文本。提示框除了顯示OK和Cancel按鈕之外 ,還會顯示一個文本輸入域,用來輸入文本內容。該方法接收兩個參數:要顯示給用戶的文本提示和文本輸入域的默認值(可以是一個空字符串) */ var result = prompt("What is your name? ", ""); if (result !== null) { alert("Welcome, " + result); } </script>
history對象
history對象保存著用戶上網的歷史記錄,從窗口被打開的那一刻算起。因為history是window對象的屬性,因此每個浏覽器窗口、每個標簽頁以及每個框架,都有自己的history對象與特定的window對象關聯。處於安全方面的考慮,開發人員是無法知道用戶浏覽過的URL,不過,借助用戶訪問過的頁面列表,同樣可以在不知道實際URL的情況下實現後退和前進。
使用Go()方法可以在用戶的歷史記錄中任意跳轉,可以向後也可以向前。該方法接收一個參數:表示向前或者向後跳轉的頁面數的整數值。負數表示向後跳轉(類似單擊浏覽器的後退按鈕),正數表示向前跳轉(類似浏覽器的前進按鈕)。
//後退一頁 history.go(-1); //前進一頁 history.go(1);
也可以給go()方法傳遞一個字符串參數,此時浏覽器會跳轉到歷史記錄中包含該字符串的第一個位置–可能後退也可能前進,具體要看哪個位置最近。如果歷史記錄中不包含該字符串,那麼這個方法什麼也不做
//跳轉到最近的jb51.net history.go("jb51.net");
另外,還可以使用back()和forward()來代替go()方法
//後退一頁 history.back(); //前進一頁 history.forward();
除此之外,history對象還有一個length屬性,保存著歷史記錄的數量。這個數量包括所有的歷史記錄,即所有的向後和向前的記錄。如果history.length==0,則表示這是用戶打開窗口後的第一個頁面
history對象不常用,但是在創建自定義的後退和前進按鈕,以及檢測當前頁面是不是用戶歷史記錄的第一個頁面時,還是必須使用它。
Demo1
history.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>history</title> </head> <body> <form> <input type="text" id="username"> </form> <input type="button" id="btn" value="按鈕" onclick="go()"> <script type="text/javascript"> function go(){ var name=document.getElementById("username").value; if(name=="hello"){ history.go(-1); }else{ alert('用戶名不正確'); } } </script> </body> </html>
ceshi.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=""> </head> <body> <a href="history.html" >跳轉</a> </body> </html>
這裡使用history模仿了一個輸入用戶名之後。跳轉到之前頁面的例子。
Demo2
history2.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>history</title> </head> <body> <a href="demo.html">跳轉</a> <input type="button" id="btn" value="前進" onclick="go()"> <script type="text/javascript"> function go(){ history.forward(); } </script> </body> </html>
demo.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=""> </head> <body> <input type="button" name="" value="回退" id="btn" onclick="fn()"> <script type="text/javascript"> function fn(){ history.back(); } </script> </body> </html>
這個小例子模擬了history.back()和history.forward()的基本功能
以上就是小編為大家帶來的JS中BOM相關知識點總結(必看篇)全部內容了,希望大家多多支持~