使用eventlistener将项目推送到数组中

时间:2016-10-15 08:36:52

标签: javascript arrays addeventlistener event-listener array-push

一旦用户点击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);

}

基本上,在单击项目后,主阵列需要使用他们单击的内容进行更新。

任何帮助将不胜感激。

谢谢

4 个答案:

答案 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.

我通过执行selectionsthis.selections = []数组显式绑定到您的函数范围,然后通过执行var that = this在Click侦听器中设置此上下文。

重申问题:

您在getSelection方法中绑定了事件侦听器,只调用一次。但是,点击可能会在以后的任何时间发生。所以你需要确保两件事:

  1. selections事件处理程序中引用的click数组是getSelection方法范围内定义的数组。
  2. 不知何故,即使执行getSelection方法,也要保留class Video(models.Model): name = models.CharField(max_length=200) description = models.TextField(blank=True, null=True) 方法的范围。
  3. 闭包,神奇地解决了这两个问题。 :)

    关于使用闭包的原因的一个很好的起点是this