2016-04-28 94 views
0

我想知道爲什麼這個JavaScript不起作用設置:事件監聽器上錯elment

var element = document.querySelector('#element1'); 
var button= document.querySelector('#button1'); 
button.addEventListener('click', function() { 
    element.doSomething(); 
}); 

var element = document.querySelector('#element2'); 
var button= document.querySelector('#button2'); 
button.addEventListener('click', function() { 
    element.doSomething(); 
}); 

按鈕都正在做的事情爲「element2的」。

是不是像事件監聽器保持指向變量而不是它的值的指針?

謝謝您的回答

+2

爲什麼對這兩個變量同名?後面的一個覆蓋了以前定義的那個。 – Tushar

+1

相關:[JavaScript關閉如何工作?](http://stackoverflow.com/q/111102/218196) –

回答

1

可以包裹與匿名的塊級的代碼;自我執行功能。

這與使用Java中的花括號包裝代碼塊{ /* {{code}} */ }時類似。你可以有重複的變量,只要它們存在於它們自己的塊中。

這樣,變量可以是相同的。你應該真的創建一個單獨的函數並傳入選擇器ID;特別是如果他們正在做同樣的事情。

(function() { 
 
    HTMLDivElement.prototype.doSomething = function() { 
 
    this.innerHTML = this.innerHTML == 'Hello' ? 'Goodbye' : 'Hello'; 
 
    } 
 
}()); 
 

 
(function() { 
 
    var element = document.querySelector('#element1'); 
 
    var button = document.querySelector('#button1'); 
 
    button.addEventListener('click', function() { 
 
    element.doSomething(); 
 
    }); 
 
}()); 
 

 
(function() { 
 
    var element = document.querySelector('#element2'); 
 
    var button = document.querySelector('#button2'); 
 
    button.addEventListener('click', function() { 
 
    element.doSomething(); 
 
    }); 
 
}());
div { 
 
    display: inline-block; 
 
    width: 5em; 
 
    height: 2em; 
 
    border: thin solid black; 
 
    text-align: center; 
 
    line-height: 2em; 
 
    margin-bottom: 0.25em; 
 
}
<div id="element1">?</div> 
 
<input type="button" id="button1" value="Button 1" /> 
 
<br /> 
 
<div id="element2">?</div> 
 
<input type="button" id="button2" value="Button 2" />

你應該試試這個。

function addButtonClick(btnSelectorId, elSelectorId) { 
    document.querySelector(btnSelectorId).addEventListener('click', function() { 
    document.querySelector(elSelectorId).doSomething(); 
    }); 
} 

addButtonClick('#button1', '#element1'); 
addButtonClick('#button2', '#element2'); 
0

試試這個,你給同名兩個元素&按鈕被覆蓋前一個:

var element1 = document.querySelector('#element1'); 
var button1= document.querySelector('#button1'); 
button1.addEventListener('click', function() { 
    element1.doSomething(); 
}); 

var element2 = document.querySelector('#element2'); 
var button2 = document.querySelector('#button2'); 
button2.addEventListener('click', function() { 
    element2.doSomething(); 
}); 
+0

是的我知道,我不是要求更正代碼,但要理解爲什麼它不起作用一個較低的水平 – Tribes

+0

是的,新的價值取代了以前的價值。 –

0

的問題是,你引用的elment變量裏面的你的事件處理函數。當您爲elment分配新值時,您將更改其值並影響這兩個處理程序。

解決辦法:每件都用不同的變量名:

var element1 = document.querySelector('#element1'); 
var button = document.querySelector('#button1'); 
button.addEventListener('click', function() { 
    element1.doSomething(); 
}); 

var element2 = document.querySelector('#element2'); 
var button = document.querySelector('#button2'); 
button.addEventListener('click', function() { 
    element2.doSomething(); 
}); 

或者更好的是,或許,破除封閉變量乾脆,只是查詢需要:

document.querySelector('#button1').addEventListener('click', function() { 
    var element = document.querySelector('#element1'); 

    element.doSomething(); 
}); 

document.querySelector('#button2').addEventListener('click', function() { 
    var element = document.querySelector('#element2'); 

    element.doSomething(); 
}); 
+0

好的,所以你說內部函數是在「main」函數的末尾進行評估的? – Tribes

+0

@Tribes不,在單擊事件發生時評估內部函數,這可能是代碼初始運行後的幾秒,幾分鐘或幾小時。 – JLRishe

0

你是對這兩個元素使用相同的變量,因此最後聲明的變量是將要使用的變量。
例如:

x = "Hello"; 
x = "World"; 
console.log(x); //This will print out "World" 

需要聲明他們作爲不同的變量。與您的代碼示例(注意我改變第二元件):

var elment = document.querySelector('#element1'); 
var button= document.querySelector('#button1'); 
button.addEventListener('click', function() { 
    elment.doSomething(); 
}); 

var elment2 = document.querySelector('#element2'); //Changed to elment2 
var button2 = document.querySelector('#button2'); //Changed to button2 
button2.addEventListener('click', function() { 
    elment2.doSomething(); 
}); 
+0

是的,但是 x =「你好」; console.log(x); //這將打印出「你好」 x =「世界」; console.log(x); //這將打印出「World」 – Tribes

+0

@Tribes這是因爲您正在將值寫入控制檯。事件處理程序在添加時不會立即執行;他們在事件發生時執行。 – JLRishe

+0

@tribes的事情是事件是在DOM加載時註冊的,這讓瀏覽器取代了這些值:)。 –