天天看點

element.onclick = fun與element onclick="fun()"的差別

原本标題是:element.onclick = fun與<element οnclick="fun()">的差別,但是提示含有非法字元。

問題背景:

在看this指向的時候看到了這個,有的時候通過給DOM元素綁定監聽事件,來觸發某些事件處理函數(如點選目前元素時修改該元素樣式等),如果綁定的監聽函數裡面用到了this,上面兩種方式可能會有不同的效果。

試驗代碼:

<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <title>差別onclick不同綁定方式</title>
</head>
<body>
<div id="div1" style="width: 80px;height: 80px" >DIV1,點選觸發更改顔色</div>
<div id="div2" style="width: 80px;height: 80px" onclick="changeBackground2()">DIV2,點選觸發更改顔色</div>
<script>
  //this指向目前元素,本質是調用對象裡面的方法
  div1.onclick = changeBackground1;
  function changeBackground1(){
    console.log(this);
    this.style.color = '#cc0000';
  }

  //this指向window對象,本質是調用了嵌套函數,先調用onclick(),再調用changeBackground()
  //嵌套函數中的this要麼指向window(非嚴格模式)要麼undefined(嚴格模式)
  function changeBackground2() {
    console.log(this);
    this.style.color = '#cc0000';  //TypeError:color undefined
  }
</script>
</body>
</html>
           

試驗結果:

element.onclick = fun與element onclick="fun()"的差別

可以很明顯的看到,第一種方式達到了想要的效果,第二種方式直接報錯了。通過控制台列印的内容和報的錯能夠分析出基本原因,this指向不同,第一個指向了div元素(div1),顔色修改成功,第二個指向了window對象,找不到color屬性報錯。為什麼this的指向會不一樣?

原因分析:

1.copying

element.onclick = doSomething;
           

這個實際上是把doSomthing這個函數複制一份給了element的onclick屬性,是以觸發點選事件時,this指向的是運作時調用它的對象element。原解釋:The function is copied in its entirety to the 

onclick

 property (which now becomes a method). So if the event handler is executed 

this

 refers to the HTML element and its 

color

 is changed.

------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------      

2.referring

<element onclick="doSomething()">
           

這種方式隻是讓onclick屬性指向了函數doSomething,并沒有把doSomething函數的内部實作也包含進來,是以當觸發點選事件時,隻是找到onclick屬性,然後告訴你去找doSomething吧,我這沒具體實作,找到doSomething後,這時候裡面的this已經指向window了,其實是在window下調用的doSomething函數。原解釋:

you do not copy the function! Instead, you refer to it, and the difference is crucial. The 

onclick

 property does not contain the actual function, but merely a function call:

doSomething();
      

So it says “Go to doSomething() and execute it.” When we arrive at 

doSomething()

the 

this

 keyword once again refers to the global window object and the function returns error messages.

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------         / \           |
|          | go to doSomething() |          |            |
|          | and execute it      | ---- reference to     |
|          -----------------------       function        |
|                                                        |
----------------------------------------------------------      

3.兩個的差別就是:第一種方式是完全複制;第二種隻是指向了函數。

3.1

element.onclick = doSomething;
alert(element.onclick)
//結果如下

function doSomething()
{
	this.style.color = '#cc0000';
}
           

doSomething是element對象的一個屬性(方法),類似下面:

var element = {
            value: "123",
            onclick: function doSomething() {
                console.log(this.value);
            }
        }
element.onclick();//123
           

3.2 

<element onclick="doSomething()">
alert(element.onclick)
//結果如下

function onclick()
{
	doSomething()
}
           

doSomething是一個嵌套函數,類似下面:

var element = {
       value: "123",
       onclick: function onclick(){
           doSomething();
       }
    }
function doSomething() {
    console.log(this.value);
}
element.onclick();//undefined
           

嵌套函數中的this要麼指向window(非嚴格模式),要麼undefined(嚴格模式)

參考連結:https://www.quirksmode.org/js/this.html

https://blog.csdn.net/u013584334/article/details/81192899