2017-09-13 76 views
0

我知道這有點有趣,因爲人們經常要求解決某些不起作用的解決方案,在這種情況下,情況恰恰相反。爲什麼我的點擊事件處理程序是(YES「is」)工作?

我在玩JavaScript,發現了讓我感到困惑的東西! 我嘗試過在線尋找幫助,但找不到任何有用的主題。

問題是這樣的:在函數bar只調用一次後,onclick事件工作正常。這怎麼可能!?

但是,當我問類型的變量x的返回undefined,而不是Number,這是正常的,因爲x裏面bar

function bar() { 
    var p = document.getElementById("foo"); 
    p.onclick = showAlert; 
    var x = 5; 
    alert("bar function was called !"); 
    } 
    bar(); 

任何人都可以啓發我究竟發生了什麼,一個詳細的解釋將非常讚賞。

全碼:(的jsfiddle鏈路:https://jsfiddle.net/ge4gj5nw

<!DOCTYPE html> 
<html> 
    <head> 
    <style> 
     #foo { 
     border: solid blue 1px; 
     width: 30%; 
     padding: 10px; 
     } 
    </style> 
    </head> 
    <body> 
    <p id="foo">My Event Element</p> 
    <p>Click on the above element..</p> 
    </body> 
</html> 

<script> 
    function bar() { 
    var p = document.getElementById("foo"); 
    p.onclick = showAlert; 
    var x = 5; 
    alert("bar function was called !"); 
    } 
    bar(); 
    function showAlert(event) { 
    alert("onclick Event detected!"); 
    } 
</script> 
+1

我不很明白你在這裏問的問題。你在問爲什麼事件處理程序被調用?或者給定的範圍如何在這裏工作?或者你問爲什麼showAlert'可用? – Nit

+0

JavaScript是一種垃圾收集語言。變量或對象在未被使用時會被垃圾收集。這是通過查看該變量的執行上下文來完成的。 – liontass

+0

JavaScript中有函​​數聲明。 – acdcjunior

回答

2

即使p被限制在條形函數的範圍內getElementById將返回對DOM中的節點的引用(其範圍較高)。通過調用p.onclick = showAlert;,您可以在該函數內改變onclick屬性(更高範圍)。

只調用一次函數「bar」後,「onclick」事件是 工作得很好。這怎麼可能?

它可能是因爲調用bar突變了一個更高範圍的對象。

var global = {specialKey: 'I am global scoped'} 

function testingFunctionScope() { 
    global.specialKey = 'Not function scoped!'; 
    console.log(global.specialKey); // Not function scoped! 
} 

testingFunctionScope(); 
console.log(global.specialKey); // Not function scoped! 
+0

「這可能是因爲調用bar變更了更高範圍的對象。」 先生,您正在處理我正在尋找的內容:) 最後一個問題:變量「p」的範圍是什麼? (全球?) – Elight7

+0

'p'只在'bar'範圍內可用。這意味着p的值(由bar指定)將始終在'bar'之外引發一個參考錯誤。很高興能夠幫助! – Maxwelll

+0

「更高範圍的對象」是否是鼠標點擊事件? – Elight7

0

當 '酒吧' 功能被調用時,它更新的 'p' 元素的onclick屬性。該屬性保持設置直到頁面刷新,然後需要再次調用「bar」函數才能設置屬性。鏈接的'onclick'屬性的範圍是頁面的生命週期。這是頁面的全局。

'x'是一個局部變量,其範圍在聲明時開始,在函數結束時結束。在函數外部,頁面不知道變量'x'。

欲瞭解更多信息,查找全局變量與局部變量。

0

這就是所謂的「吊裝」,並在你的例子是提升優先級,其功能是變量聲明之前訪問。我建議你閱讀JavaScript中的提示。 關於變量x,它是「閉包」。如果我正確理解你的問題,你試圖從另一個函數調用變量「x」。

0

onclick事件正在工作,因爲在bar函數中設置了元素的onclick參數。

var p = document.getElementById("foo"); 
p.onclick = showAlert; 

您可以將這兩條線移動到條形函數之外,並獲得相同的效果,而不必具有單獨的功能。

var p = document.getElementById("foo"); 
p.onclick = showAlert; 

function showAlert(event) { 
    alert("onclick Event detected!"); 
} 

這是您在腳本標記中需要的全部內容。

單擊該元素時,將調用showAlert函數。

1

好吧,我想我知道你不明白,我準備了一小段代碼來說明。使用p.onclick的地方並不重要,當函數被綁定到那裏時,它將一直保留在DOM元素的整個生命週期中,或者直到解除綁定函數。 檢查: https://jsfiddle.net/52wq4gdv/1/ 我設置處理程序,並刪除它們取決於按下按鈕

// set vars globaly for ease of use. 
var p = document.getElementById("foo"); 
var buttonRemove = document.getElementById("remove-handler"); 
var buttonAdd = document.getElementById("add-handler"); 

function bar() { 
    p.onclick = showAlert; 
    buttonRemove.onclick = removeOnClick; 
    buttonAdd.onclick = addOnClick; 
    var x = 5; 
    alert("bar function was called !"); 
} 
bar(); 

function showAlert(event) { 
    alert("onclick Event detected!"); 
} 

function addOnClick(event) { 
    p.onclick = showAlert; 
} 

function removeOnClick(event) { 
    p.onclick = undefined; 
} 

和HTML:

<button id="foo">My Event Element</button> 
<p>Click on the above element..</p> 
<button id="remove-handler"> 
    Remove on click handler 
</button> 
<button id="add-handler"> 
    Add back on click handler 
</button> 

此URL應該清楚一些事情: https://www.w3schools.com/js/js_htmldom.asp

相關問題