一旦用户点击DOM中的元素,我就会尝试使用值更新数组。这些元素似乎被推入匿名函数内部的数组中,但在函数外部,数组仍为空。我该如何解决这个问题?这是javascript代码:
function getSelection() {
var selections = [];
var container = document.getElementById("main-container");
var choices = document.querySelectorAll('li');
choicesLength = choices.length;
for(var i = 0; i < choicesLength; i++) {
choices[i].addEventListener("click", function(){
var position = this.getAttribute("value");
selections.push(position);
// logs array and updates with each click
console.log(selections);
});
}
// logs empty array
console.log(selections);
}
基本上,在单击项目后,主阵列需要使用他们单击的内容进行更新。
任何帮助将不胜感激。
谢谢
答案 0 :(得分:0)
传递给addEventListener
的函数在事件发生之前不会运行。
您无法点击分配后立即运行的console.log
之前的任何列表项。
基本上,在点击项目后,主阵列需要使用他们点击的内容进行更新。
......那就是将要发生的事情。查看点击处理程序中console.log
的结果。
答案 1 :(得分:-1)
基本上移动selections
函数的getSelection
otuside并将其公之于众。
var selections = [];
function getSelection() {
var container = document.getElementById("main-container");
var choices = document.querySelectorAll('li');
choicesLength = choices.length;
for(var i = 0; i < choicesLength; i++) {
choices[i].addEventListener("click", function(){
var position = this.getAttribute("value");
selections.push(position);
console.log(selections);
});
}
console.log(selections);
}
window.onload = getSelection;
// access selections outside of getSelection()
setInterval(function () {
if (selections.length < 2) {
console.log('length is smaller than two.');
}
}, 1500);
<ul><li value="1">1</li><li value="2">2</li><li value="3">3</li><li value="4">4</li><li value="5">5</li><li value="6">6</li></ul>
答案 2 :(得分:-1)
这是关于Javascript范围的,你可以在这里更多地了解它:
Learn more about Javascript Scoping and hoisting
第一个console.log(选择)是本地的,而最后一个console.log(选择)是 是全球的,两者不一样,这就是为什么它是空的。 以下是我的解决方案的编辑形式:
function getSelection() {
var selections = [];
var container = document.getElementById("main-container");
var choices = document.querySelectorAll('li');
choicesLength = choices.length;
for (var i = 0; i < choicesLength; i++) {
choices[i].addEventListener("click",pushArray(i));
}
function pushArray(elm) {
var position = choices[elm].getAttribute("value");
selections.push(position);
// logs array and updates with each click
console.log(selections);
}
// logs empty array
console.log(selections);
}
document.body.addEventListener("load", getSelection());
<ul>
<li value="1">1</li>
<li value="2">2</li>
<li value="3">3</li>
<li value="4">4</li>
<li value="5">5</li>
<li value="6">6</li>
<li value="7">7</li>
<li value="8">8</li>
<li value="9">9</li>
<li value="10">10</li>
</ul>
答案 3 :(得分:-1)
添加到我的评论中,我认为闭包可以非常有效地解决这个问题。
我还没有测试过以下代码:
function getSelection() {
this.selections = [];
var container = document.getElementById("main-container");
var choices = document.querySelectorAll('li');
choicesLength = choices.length;
var that = this;
for(var i = 0; i < choicesLength; i++) {
choices[i].addEventListener("click", function(){
var position = this.getAttribute("value");
that.selections.push(position); //Explicitly specify context
// logs array and updates with each click
console.log(that.selections);
});
}
return function(){
this.selections;
}
}
您可以像这样调用getSelection
函数:
var getUpdatedArray = getSelection();
//At a later stage when you want the array just do:
getUpdatedArray(); //This should return the selections array.
我通过执行selections
将this.selections = []
数组显式绑定到您的函数范围,然后通过执行var that = this
在Click侦听器中设置此上下文。
重申问题:
您在getSelection
方法中绑定了事件侦听器,只调用一次。但是,点击可能会在以后的任何时间发生。所以你需要确保两件事:
selections
事件处理程序中引用的click
数组是getSelection
方法范围内定义的数组。getSelection
方法,也要保留class Video(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(blank=True, null=True)
方法的范围。闭包,神奇地解决了这两个问题。 :)
关于使用闭包的原因的一个很好的起点是this。