今天寫了個js的demo,遇到了個小問題,后來發現是自己對window.onload()的具體用處不是太清楚,現在跟大家分享一下。
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>window_onload()</title> <meta name="author" content="blck" /> <!-- Date: 2015-03-24 --> <script type="application/javascript"> window.onload = function(){ var obj = document.getElementById("btn"); function f(){ alert("show me"); } } </script> </head> <body> <button id="btn" onclick="f()">click</button> </body>
當函數f()放在window.onload()=function(){}內部的時候,點擊按鈕並不能夠調用f()成功彈出對話框。並且控制台顯示
Uncaught ReferenceError:f is not defined
也就是函數f()就沒有被定義。
但是如果將function f()移到window.onload()=function(){}外部,也就是如下的時候,程序就能正常運行。
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>window_onload()</title> <meta name="author" content="blck" /> <!-- Date: 2015-03-24 --> <script type="application/javascript"> window.onload = function(){ var obj = document.getElementById("btn"); } function f(){ alert("show me"); } </script> </head> <body> <button id="btn" onclick="f()">click</button> </body>
為什么會這樣呢?window.onload事件難道不是在頁面加載完時候就去執行嗎?
沒錯,我們來理一下其中的思路。
首先,window.onload事件是在整個頁面包括dom結構、圖片等等全部加載完成之后才會觸發。
其次,HTML加載時由上往下的,在HTML加載的時候,遇到function關鍵字,聲明一個函數的時候,就會在內存中開辟一個新的空間來對函數進行存儲,方便以后進行調用。
所以,當將function f()寫到window.onload()=function(){}內部的時候,需要整個頁面加載完成的之后,才聲明這個函數,也就意味着,當HTML加載到onclick="f()"的時候,window.onload=function(){}里面的函數f還沒有被聲明,這時候內存中就找不到function f(),於是就會報錯。
那么,將function f()移到window.onload()=function(){}外,則HTML加載到<head></head>的時候就會聲明函數f了,所以進行onclick綁定的時候就能夠在內存中找到f()並進行調用。
除了這是涉及HTML加載順序的問題,還有一點就是可以從函數作用域這方面去考慮。寫在window.onload()=function(){}內部的function f()就是在一個匿名函數內部的局部函數,並不是全局函數,所以onclick="f()"調用的時候是調用不到的。
但是如果你在第一段代碼中,function f()函數后面加上obj.onclick = f;那程序就又能正常運行了。這是因為直接將函數f綁定給obj對象點擊事件上了,所以就不在window.onload()=function(){}的作用域下,就可以成功調用該函數了!
提到window.onload事件,補充說明一下它與jquery中的$(document).ready()的區別:
$(document).ready()是在DOM結構繪制完畢之后就執行內部的語句了,不用像window.onload一樣,需要等到全部元素都加載完畢才執行。