简体   繁体   English

将事件监听器添加到chrome-extension中for循环的复选框中

[英]Adding eventListeners to checkboxes in for loop in chrome-extension

I have a function that gets all the tabs in a window and then updates the popup.html page by adding a checkbox for each tab. 我有一个函数,它可以获取窗口中的所有选项卡,然后通过为每个选项卡添加一个复选框来更新popup.html页面。 After doing this there is a second for loop that adds event listeners which update an dictionary containing the value of the checkbox's. 完成此操作后,第二个for循环添加了事件侦听器,该事件侦听器更新了包含复选框值的字典。 The problem is that any checkbox I click only updates the last element in the dictionary. 问题是我单击的任何复选框仅更新字典中的最后一个元素。

Here is the code: 这是代码:

function viewTabs() {
  var queryInfo = {lastFocusedWindow: true};
  // Go through all the tabs open, and add them to the scrollview along with a number and checkbox
  chrome.tabs.query(queryInfo, function(tabs) {
    document.getElementById("openLinks").innerHTML = "";
    (function() {
      for (i = 0; i < tabs.length; i++) {
        // add checkboxes to each link for the user to include or disclude
        document.getElementById("openLinks").innerHTML += 
            "<li><input type=\"checkbox\" id = \"" + i.toString() + "\" checked>" + 
            tabs[i].title + "</li>";
        checkedTabsArr[i.toString()] = true;
      }
      for (i = 0; i < tabs.length; i++) {
        document.getElementById(i.toString()).addEventListener("click",
          function() {
            console.log(checkedTabsArr);
            checkedTabsArr[i.toString()] = !checkedTabsArr[i.toString()];
        });
      }
    }());
  });
}

Here is the output (I am clicking different checkboxes not just 6): 这是输出(我单击的是多个复选框,而不仅仅是6个):

Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true}
Buttons.js:174 Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true}
Buttons.js:174 Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: false}
Buttons.js:174 Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true}
Buttons.js:174 Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: false}
Buttons.js:174 Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true}
Buttons.js:174 Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: false}
Buttons.js:174 Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true}
Buttons.js:174 Object {0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: false}

I have tried with and without closures. 我尝试了有无闭包。

Why are you using two separate for loops inside the same context? 为什么在同一上下文中使用两个单独的for循环?

EDIT I've tracked this down to an issue with how javascript handles both click and change events with checkboxes. 编辑我已经将其归结为javascript如何处理复选框的点击和更改事件的问题。

Note: Don't ever use click events for checkboxes, use onChange instead. 注意:请勿将click事件用于复选框,而应使用onChange Also, don't assign onchange using javascript. 另外,请勿使用JavaScript分配onchange It fails spectacularly for some reason that I can't identify. 由于我无法确定的某些原因,它失败了。

Instead, use jQuery for it. 而是使用jQuery。 Make sure you have the jQuery library included on your page and load your script after all DOM elements are loaded on the page. 确保页面上包含jQuery库,并在页面上加载所有DOM元素后加载脚本。 Then this code should work for you just fine: 然后这段代码就可以为您工作:

function viewTabs() {
    var queryInfo = {
        lastFocusedWindow: true
    };

    // Go through all the tabs open, and add them to the scrollview along with a number and checkbox
    chrome.tabs.query(queryInfo, function (tabs) {

        for (i = 0; i < tabs.length; i++) {
            var thisTab = tabs[i];

            // add checkboxes to each link for the user to include or disclude
            // start by creating a blank checkbox element
            var thisCheckbox = document.createElement('input');
            thisCheckbox.type = "checkbox";
            thisCheckbox.id = i;
            thisCheckbox.checked = true;

            //Add the event listener to the newly created checkbox
            attachChangeListener(thisCheckbox, i);
            console.log(thisCheckbox);

            // create a blank <li>
            var thisListItem = document.createElement('li');

            // add the checkbox and tab title to <li>
            thisListItem.appendChild(thisCheckbox);
            thisListItem.appendChild(document.createTextNode(thisTab.title));

            // add <li> to the end of the openLinks element and add a new value to the array
            document.getElementById("openLinks").appendChild(thisListItem);
            checkedTabsArr[i] = true;

            console.log(tabs[i].title + ": " + thisCheckbox.checked);

        }

        function toggle(checkbox, title) {
            console.log("CLICK EVENT FOR: " + title);

            //toggle the state of the checkbox
            checkbox.checked = !checkbox.checked;
            console.log(title + " updated: " + checkbox.checked);


        }

        function attachChangeListener(element, index) {
            $(element).change(function () {
                if ($(this).is(":checked")) {
                    //match the array's value to that of the new checkbox state
                    checkedTabsArr[index] = true;
                    console.log(checkedTabsArr);
                } else {
                    //match the array's value to that of the new checkbox state
                    checkedTabsArr[index] = false;
                    console.log(checkedTabsArr);
                }
            });
        }
    });

The above code should hopefully be a plug and play solution for you. 上面的代码有望为您提供即插即用的解决方案。

Let me know how this goes for you. 让我知道这对您的影响。

Fiddle: https://jsfiddle.net/wof8ebq7/27/ 小提琴: https : //jsfiddle.net/wof8ebq7/27/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM