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>
視窗關係和框架
如果頁面中包含框架,則每個框架都擁有自己的winframdowes,並且保存在集合中。在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.php.cn“)
這樣就可以立即打開新的URL並在瀏覽器的記錄中產生一筆記錄。
同樣的,將location.href和window.location設定為一個URL值,也會以此值呼叫assign()方法。
location.href=”http://www.php.cn”;
window.location=”http://www.php.cn”;
這兩種方式的效果和顯示調用assign()方法效果完全一樣
此外,透過修改location物件的其他屬性也可以改變目前載入的頁面。
每次修改location的屬性(hash除外),頁面都會以新的URL重新載入。修改hash的值會在瀏覽器的歷史記錄中產生一條新的記錄
在url:http://a.com#helloword中的'#helloworld'就是location.hash,改變hash並不會導致頁面刷新,所以可以利用hash值來進行資料傳遞,當然資料容量是有限的。
當透過上述任何一種方法修改URL之後,瀏覽器的歷史記錄中就會產生一條新紀錄,因此透過點擊」後退」按鈕都會導覽到前一個頁面。
我們可以使用replace()方法來停用這種行為。此方法只接受一個參數,即要導航到的URL;結果雖然會導致瀏覽器位置改變,但不會在歷史記錄中產生新紀錄。在呼叫replace()方法後,使用者不能回到前一個頁面。
這個頁面載入到瀏覽器後,瀏覽器就會在1秒鐘後重新導向到www.php.cn。然後,'後退'按鈕將處於停用狀態,如果重新輸入完整的URL,則無法返回範例頁面。
<script type="text/javascript"> setTimeout(function () { location.replace("http://www.php.cn/"); }, 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()方法传递一个字符串参数,此时浏览器会跳转到历史记录中包含该字符串的第一个位置–可能后退也可能前进,具体要看哪个位置最近。如果历史记录中不包含该字符串,那么这个方法什么也不做
//跳转到最近的php.cn history.go("php.cn");
另外,还可以使用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()的基本功能