在 chrome-extension 的 for 循环中将 eventListeners 添加到复选框

Adding eventListeners to checkboxes in for loop in chrome-extension

我有一个函数可以获取 window 中的所有选项卡,然后通过为每个选项卡添加一个复选框来更新 popup.html 页面。这样做之后,有第二个 for 循环添加事件侦听器,更新包含复选框值的字典。问题是我单击的任何复选框只会更新字典中的最后一个元素。

代码如下:

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()];
        });
      }
    }());
  });
}

这是输出(我点击了不同的复选框,而不仅仅是 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}

我试过使用和不使用闭包。

为什么要在同一上下文中使用两个单独的 for 循环?

编辑 我已将此归结为 javascript 如何处理带有复选框的单击和更改事件的问题。

注意:永远不要对复选框使用点击事件,请改用 onChange。另外,不要使用 javascript 分配 onchange。由于某种我无法确定的原因,它失败了。

相反,请使用 jQuery。 确保页面上包含 jQuery 库,并在页面上加载所有 DOM 元素后加载脚本。那么这段代码应该对你有用:

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);
                }
            });
        }
    });

以上代码有望成为您的即插即用解决方案。

让我知道你的情况如何。

Fiddle: https://jsfiddle.net/wof8ebq7/27/