所有,我现在已经尝试了几个小时不同的东西,但我无法解决这个问题,我有这个函数接受JSON -
我可以createElement('a')
:精细
我可以set
所有元素属性,例如href
等:FINE
我可以appendChild(a)
使用必需的元素tags
:FINE
但我无法设置a.addEventListener("click", function () { alert("clicked - " + a.id) }, false);
每次点击任何href,它都会显示最后一个值
function setTags(tagsJson) {
var obj = JSON.parse(tagsJson);
var a = null;
var linkText = null;
for (var i = 0; i < obj.length; i++) {
if (typeof (obj[i].Tag_name) === 'undefined' || obj[i].Tag_name === null) {
// DO NOTHING
}
else
{ a = document.createElement('a');
linkText = document.createTextNode(obj[i].Tag_name);
a.appendChild(linkText);
a.href = "#";
a.textContent = obj[i].Tag_name;
a.className = "badge badge-success";
document.getElementById("tags").appendChild(a);
// HERE IS THE ISSUE
a.addEventListener("click", function () { alert("clicked - " + a.textContent) }, false);
}
}
}
如果JSON具有以下值
的示例 {\"Tag_id\":12,\"Tag_name\":\"Aston Martin\"},{\"Tag_id\":13,\"Tag_name\":\"Cars\"}]"}
它应该在textContent
添加唯一的文字,例如'Aston Martin','Auston'和'Cars',但点击任何项目后,alter会显示为Cars
,尽管链接中的文字显示正确的价值观
根据上面的截图,我可以看到文本值很好,但addEventListener只显示CLICK上的最后一个值
我想我错过了对addEventListener
的理解?
我该如何解决这个问题
干杯
答案 0 :(得分:3)
而不是a.textContent
使用this.textContent
a.addEventListener("click", function () { alert("clicked - " + this.textContent) }, false);
当执行事件侦听器时, for-loop 已经执行,直到i < obj.length
满足为止,这就是为什么a
永远是最后一个。
答案 1 :(得分:1)
只有在单击该项时才会触发该函数,因此当您单击该项时,将获取在for循环之外声明的变量a,并且a保留循环中的最后一项。
不使用变量a而是使用单词 this 将当前上下文用于函数。
a.addEventListener("click", function () { alert("clicked - " + this.textContent) }, false);
答案 2 :(得分:1)
这是因为您编写警报功能的方式:
a.addEventListener("click", function(){
alert("clicked - " + a.textContent); // <---- THIS LINE
}, false);
在该行中,a.textContent
将获得textContent
的{{1}}值。
在您的实现中,a
的值正在改变每个循环。因此,函数获得的a
值将是最后一个循环的a
值。因此,您始终只能获得a
的最后一个值。
要解决此问题,您可以使用其他方式在函数中调用a
。
根据您当前的实施情况,有两种方式:
一:使用a.textContent
event.target
二:使用a.addEventListener("click", function(event){
// event is an event object passed by the `addEventListener` function
// where event.target === the DOM element that activates the listener
alert("clicked - " + event.target.textContent);
}, false);
this
工作示例
a.addEventListener("click", function(){
// `this` value === the element that activates this event listener.
alert("clicked - " + this.textContent);
}, false);
var json = "[{\"Tag_id\":12,\"Tag_name\":\"Aston Martin\"},{\"Tag_id\":13,\"Tag_name\":\"Cars\"}]";
setTags(json);
function setTags(tagsJson) {
var obj = JSON.parse(tagsJson);
var a = null;
var linkText = null;
for (var i = 0; i < obj.length; i++) {
if (typeof obj[i].Tag_name === 'undefined' || obj[i].Tag_name === null) {
// DO NOTHING
}
else
{ a = document.createElement('a');
linkText = document.createTextNode(obj[i].Tag_name);
a.appendChild(linkText);
a.href = "#";
a.textContent = obj[i].Tag_name;
a.className = "badge badge-success";
document.getElementById("tags").appendChild(a);
// HERE IS THE ISSUE
a.addEventListener("click", function () { alert("clicked - " + this.textContent) }, false);
}
}
}
a {
display: block;
}
答案 3 :(得分:0)
这是对闭包的典型误用。
您在for循环之外声明了a
变量,更重要的是您的点击回调函数。因此,当您迭代时,您的a
会被覆盖。最后,每次调用click函数时,a
都会将其值设置为for循环期间设置的最后一个值。
所以在你的情况下,你总是有
a.textContent = obj[obj.length - 1].Tag_name;
要使其按预期工作,您需要从点击事件本身检索<a>
。这可以这样做
a.addEventListener("click", function (event) { // use event here to find your element
const a = document.getElementById(event.target.id); // This is the element that was clicked
alert("clicked - " + a.textContent)
}, false);
答案 4 :(得分:0)
导致for-loop
之后的函数绑定for (var i = 0;i<10;i ++){
aLis[i].onclick = (function(num){
return function(){
alert(num)
};
})(i);
}
看看这个: