以前講過的onclick,onblur,onfocus都屬於事件操做html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #test{ background-color: red; width: 300px; height: 400px; } </style> </head> <body> <div id="test"> abcd </div> <script> var mydiv = document.getElementById("test"); mydiv.onclick = function () { console.log("123456"); } </script> </body> </html>
代碼:能夠看到內容是一塊, 內容的樣式(style)是一塊, 內容的行爲(script)是一塊, 都是相分離的,編寫前端的標準就應該使用分離的方式編寫。前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1" width="300px"> <tr onmouseover="t1(0);" onmouseout="t2(0);"><td>1</td><td>2</td><td>3</td></tr> <tr onmouseover="t1(1);" onmouseout="t2(1);"><td>1</td><td>2</td><td>3</td></tr> <tr onmouseover="t1(2);" onmouseout="t2(2);"><td>1</td><td>2</td><td>3</td></tr> </table> <script> function t1(n) { var myTrs = document.getElementsByTagName("tr")[n]; myTrs.style.backgroundColor = "red"; } function t2(n) { var myTrs = document.getElementsByTagName("tr")[n]; myTrs.style.backgroundColor = ""; } </script> </body> </html>
代碼說明
onmouseover:當鼠標聚焦在tr標籤上時會調用t1這個函數,且會將0、一、2參數傳給函數;
t1函數:經過TagName調用tr標籤,並根據[n]來獲取tr標籤的下標,下標0表示第一個tr標籤;
t1函數中會讓背景顏色變成紅色。
onmouseout:當鼠標離開tr標籤時會調用t2函數;
t2函數:會將背景顏色清空。面試
上2圖:當鼠標聚焦在哪個tr標籤上時,背景顏色就會變成紅色,鼠標離開時就清空顏色。ide
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1" width="300px"> <tr><td>1</td><td>2</td><td>3</td></tr> <tr><td>1</td><td>2</td><td>3</td></tr> <tr><td>1</td><td>2</td><td>3</td></tr> </table> <script> var myTrs = document.getElementsByTagName("tr"); var len = myTrs.length; for(var i=0;i<len;i++){ myTrs[i].onmouseover = function () { this.style.backgroundColor = "red"; }; myTrs[i].onmouseout = function () { this.style.backgroundColor = ""; } } </script> </body> </html>
代碼說明
myTrs獲取全部tr標籤。
len獲取myTrs長度。
經過for循環調用函數。
this表示誰調用當前這個函數,這個this就表示是誰; 當前是myTrs這個標籤調用function這個匿名函數,因此這個this表示鼠標所觸發的myTrs標籤; 這裏爲何不能直接使用myTrs[i]呢,這是由於當代碼執行事後由於for循環,當前的i等於下標2,此時不管咱們鼠標放在哪裏這個i都是2,不能達到咱們觸發標籤的效果,而使用this能夠觸發當前鼠標所在標籤並將其背景色改成紅色。函數
在實際中項目通常使用方法2的方式,這個方式作到了內容、行爲、樣式分離。this
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #test{ background-color: red; width: 300px; height: 400px; } </style> </head> <body> <div id="test"> abcd </div> <script> var mydiv = document.getElementById("test"); mydiv.addEventListener("click",function () { console.log('aaa') },false); mydiv.addEventListener("click",function () { console.log('bbb') },false); </script> </body> </html>
代碼
經過使用addEventListener能夠多同一個事件,屢次綁定。code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #main{ background-color: red; width: 300px; height: 400px; } #content{ background-color: pink; width: 150px; height: 200px; } </style> </head> <body> <div id="main"> <div id="content"></div> </div> <script> var mymain = document.getElementById("main"); var mycontent = document.getElementById("content"); mymain.addEventListener("click",function () { console.log("main"); },false); mycontent.addEventListener("click",function () { console.log("content"); },false); </script> </body> </html>
代碼說明
false表示從下到上顯示行爲事件;默認等於false。htm
上圖:點擊粉色部分,至關於同時點擊了content標籤和main標籤; 在代碼中正常應該從上到下執行,可是若是是false的話就從下到上執行,若是是true的話就是從上到下執行。對象
先來看個常見的面試題以下:seo
var a = 10; function test(){ alert(a); //undefined var a = 20; alert(a); //20 } test();
疑問: 爲何呢?test()執行時,雖然a=20沒有賦值,可是父級做用域裏是有a=10的,不該該是undefined呀,js是按順序執行的,此時的var num = 20;根本沒有執行,因此應該是10!!你是否是也是這麼認爲的,就和我當初同樣???
分析: 衆所周知,js代碼是自上而下執行的,JavaScript並非傳統的塊級做用域,而是函數做用域。JavaScript引擎會在代碼執行前進行詞法分析,因此事實上,js運行分爲此法分析和執行兩個階段。
JavaScript代碼運行前有一個相似編譯的過程即詞法分析,詞法分析主要有三個步驟:
分析參數
再分析變量的聲明
具體步驟以下:
函數在運行的瞬間,生成一個活動對象(Active Object),簡稱AO
第一步:分析參數:
1.函數接收形式參數,添加到AO的屬性,而且這個時候值爲undefined,即AO.name=undefined
2.接收實參,添加到AO的屬性,覆蓋以前的undefined
第二步:分析變量聲明: 如var name;或var name='mary';
1.若是上一步分析參數中AO尚未name屬性,則添加AO屬性爲undefined,即AO.name=undefined
2.若是AO上面已經有name屬性了,則不做任何修改
第三步:分析函數的聲明:
若是有function name(){}把函數賦給AO.name ,覆蓋上一步分析的值
分析下面這個例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> var a = 10; function test(a){ console.log(a); //function a (){} var a = 20; console.log(a); //20 function a (){} console.log(a); //20 } test(100); </script> </body> </html>
詞法分析:
第一步,分析函數參數:
形式參數:AO.a = undefined 接收實參:AO.a = 100
第二步,分析局部變量:
第4行代碼有var a,可是此時已有AO.a = 100,因此不作任何修改,即AO.a = 100
第三步,分析函數聲明:
第6行代碼有函數a,則將function a(){}賦給AO.a,即AO.a = function a(){}
執行代碼時:
第3行代碼運行時拿到的a時詞法分析後的AO.a,即AO.a = function a(){}; 第4行代碼:將20賦值給a,此時a=20; 第5行代碼運行時a已經被賦值爲20,結果20; 第6行代碼是一個函數表達式,因此不作任何操做; 第7行代碼運行時還是20;
舉例:
var a = 10; function test(a){ var a; //證實詞法分析第二步。 alert(a); //100 a = 20; alert(a); //20 } test(100);
舉例:
var a = 10; function test(a){ alert(a); //100 var a = 20; alert(a); //20 a = function(){} //是賦值,只有在執行時纔有效 alert(a); //function(){} } test(100);
舉例:
var a = 10; function test(a){ alert(a); //100 var a = 20; alert(a); //20 var a = function(){} //是賦值,只有在執行時纔有效 alert(a); //function(){} } test(100);
補充說明:函數聲明與函數表達式
//函數聲明 function a(){ } //函數表達式 var b = function(){ }
a和b在詞法分析時,區別:
a在詞法分析時,就發揮做用; b只有在執行階段,才發揮做用。