因爲本人學習js學不久,因此,今天恰好遇到了一個關於在window.onload裏面定義函數,而後在html裏面調用函數時出現錯誤。具體見下面:html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <script > window.onload = function () { //綁定兩個輸入框var Ow_before = document.getElementById('w_before'); var Ow_after = document.getElementById('w_after'); //定義調用函數bianhuan,而後在HTML中用button的點擊事件onclik調用。 function bianhuan(the_option) { switch (the_option) { case 'covert_upper': Ow_after.value = (Ow_before.value).toUpperCase(); console.log("大寫轉換成功!") break; case 'covert_lower': Ow_after.value = (Ow_before.value).toLowerCase(); default: console.log("轉換失敗!"); } } } </script> <body> 請輸入英文字母:<input id="w_before" type="text"></br> <input type="button" id="cover_upper" value="轉大寫" onclick="bianhuan('covert_upper')">
<input type="button" id="cover_lower" value="轉小寫" onclick="bianhuan('covert_lower')"></br> 轉換後的英文字母:<input type="text" id="w_after"> </body> </html>
運行後出現下面錯誤:顯示我要調用的bianhuan函數未定義!瀏覽器
因而我百度了一下,看到博客園的其餘前輩提供的內容,附上地址:https://www.cnblogs.com/magicgua/p/4363903.html#commentform;https://www.cnblogs.com/zxxsteven/p/9329885.html。函數
因此我整理了一下思路:學習
首先咱們得明白網頁代碼在瀏覽器中被解析後的運行順序,他們的運行順序都是遇到一條語句解析一條語句。然而從用戶角度出發,咱們的網頁當然是想先顯示出頁面的視圖層,ui
增長其友好性,再實現試圖裏面的各類功能。因此咱們的前人們想,要是咱們能夠等html語句所有解析徹底,而後再解析js語句,這樣子不就行了嗎?因而就有了相似window.onloadspa
等函數的出現,目的就爲了,等待瀏覽器解析完HTML語句,再來解析js語句。3d
因此我就是爲了解決這個問題,因而用了window.onload語句,這樣拿我上面的那個例子來講,的確把HTML的視圖層渲染出來了,按道理瀏覽器接下來就會解析個人js語句,而後成功完成我想要的功能~ 可是卻報了一個函數未定義的錯誤!我傻傻的覺得我是其餘基本邏輯語句寫錯了,因此檢查了很久,最後仍是根據上面我提到的兩位前輩的博客,才得出了答案。code
問題其實很簡單:雖然使用window.onload的想法是想要使html語句解析完,再執行js語句。但事與願違,當瀏覽器解析到 <input type="button" id="cover_upper" value="轉大寫" onclick="bianhuan('covert_upper')">這條語句時,瀏覽器就會跳到js裏去尋找這個函數,可是,它找不到!!!沒錯,找不到……orm
由於window.onload會在HTML語句所有解析徹底再執行裏面的語句,因此暫時沒法從window.onload這個做用域裏面使用這個函數,因此瀏覽器固然給咱們這個提示(函數未定義!)。htm
解決方法很簡單,把你本身定義的想要調用的函數從window.onload這個做用域裏面拿出來,放到全局做用域中。沒錯,就是下面這樣,把window.onload裏面的內容放到外面。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <script > window.onload=function(){ } var Ocover_upper = document.getElementById('cover_upper'); var Ocover_lower = document.getElementById('cover_lower'); var Ow_before = document.getElementById('w_before'); var Ow_after = document.getElementById('w_after'); function bianhuan(the_option) { switch (the_option) { case 'covert_upper': Ow_after.value = (Ow_before.value).toUpperCase(); console.log("大寫轉換成功!") break; case 'covert_lower': Ow_after.value = (Ow_before.value).toLowerCase(); default: console.log("轉換失敗!"); } } </script> <body> 請輸入英文字母:<input id="w_before" type="text"></br> <input type="button" id="cover_upper" value="轉大寫" onclick="bianhuan('covert_upper')"> <input type="button" id="cover_lower" value="轉小寫" onclick="bianhuan('covert_lower')"></br> 轉換後的英文字母:<input type="text" id="w_after"> </body> </html>
這時候你會發現,bug解決了?no ,you are too young too simple! 它會冒出另外一個問題:Cannot read property 'value' of null(大概意思呢,就是找不到這個值,這個值不存在),哈哈哈哈
其實道理和上面的同樣,執行的順序致使的,你雖然把你要調用的函數的做用域改了,讓這個函數存在於全局做用域。可是會出現另外一個問題:就是當js存在於全局做用域時,瀏覽器就會按順序一條一條執行,當執行到 Ow_after.value = (Ow_before.value).toUpperCase();這條語句時,因爲HTML語句還沒解析,瀏覽器固然找不到這個值啦,因此就會報錯(Cannot read property 'value' of null)。
此時你是否是以爲,臥槽,把要調用的函數定義再全局做用域中行不通,定義在window.onload這個局部做用域也想不通,那到底怎麼解決啊?還不如放棄了,睡覺算了,哈哈哈……
其實最終解決方法很簡單:把js代碼放到全局做用域裏邊,而後把整個<script></script>放到HTML的主體body後面,問題就解決啦~~~~
由於這樣一來,1.可使,HTML語句解析徹底,咱們在HTML裏面輸入的值能夠拿到,由於執行到js這裏時,HTML裏面的值瀏覽器已經解析,因此js已經拿到HTML裏面的值了,這樣解決了Cannot read property 'value' of null這個問題。
2.當瀏覽器解析到 <input type="button" id="cover_upper" value="轉大寫" onclick="bianhuan('covert_upper')">這條語句時,瀏覽器就會跳到js裏去尋找這個函數,此次因爲函數不是在window.onload裏面定義的,而是在全局做用域裏面定義的,因此解決了函數未定義的問題。附上代碼及截圖:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> 請輸入英文字母:<input id="w_before" type="text"></br> <input type="button" id="cover_upper" value="轉大寫" onclick="bianhuan('covert_upper')"> <input type="button" id="cover_lower" value="轉小寫" onclick="bianhuan('covert_lower')"></br> 轉換後的英文字母:<input type="text" id="w_after"> </body> <script > window.onload=function(){ } var Ocover_upper = document.getElementById('cover_upper'); var Ocover_lower = document.getElementById('cover_lower'); var Ow_before = document.getElementById('w_before'); var Ow_after = document.getElementById('w_after'); function bianhuan(the_option) { switch (the_option) { case 'covert_upper': Ow_after.value = (Ow_before.value).toUpperCase(); console.log("大寫轉換成功!") break; case 'covert_lower': Ow_after.value = (Ow_before.value).toLowerCase(); console.log("小寫也成功!"); break; default: console.log("失敗!"); } } </script> </html>
第一次寫這麼長的文章,但願個人筆記能夠幫助到一部分人,一塊兒加油。——————來自胡66。