【问题标题】:Cannot add event listener to select options in case you select same option如果您选择相同的选项,则无法将事件侦听器添加到选择选项
【发布时间】:2017-06-13 02:58:05
【问题描述】:

基本上,当 chrome.storage.local 发生更改时,下面的函数会清空选择字段并使用更新的选项重新填充它。这也是我想在选项中添加事件侦听器的时候,以便我可以实现自定义操作。

但我对此束手无策,由于某种原因,我无法在选项中添加事件侦听器。我有一个 setTimeout 函数,可以在渲染选项后打印出选项,并且选项在那里,但 onclick 为空。我还尝试使用 setTimeout 添加事件侦听器,以仔细检查它们是否在另一个步骤中被覆盖,但这也不起作用。

编辑以从反馈中澄清:控制台不显示事件侦听器回调 console.log('working'),因此它不起作用。而且我已经在使用 select onchange 监听器。但我需要重新关注“信息”字段,即使他们重新选择了相同的选项。

任何帮助将不胜感激!

function updateSelectOptions(selectID){
    var selectList = document.getElementById(selectID);
    while (selectList.length > 0) {
        selectList.remove(selectList.length -1);
    }

    var storage = chrome.storage.local;
    storage.get(['settingsArray', 'selectedPage'], function(data) {
        var settingsArray = data.settingsArray;
        var settingsNameArray = settingsArray.map(function(ele) {
            return ele.pageName;
        });
        if (selectID === 'pageSelectDropdown') {
            settingsNameArray.push('Add New Page');
        }

        var selectedPage = data.selectedPage;
        //Create and append the options
        for (var i = 0; i < settingsNameArray.length; i++) {
            var option = document.createElement("option");
            option.setAttribute("value", i);
            option.setAttribute("class", 'optionClass');
            option.text = settingsNameArray[i];
            option.addEventListener('click', ()=>{
                console.log('working')
                document.getElementById('info').focus();
            });
            selectList.appendChild(option);
        }

        document.getElementById(selectID).value = selectedPage;
    })
}

实际上,即使这个玩具示例也不起作用,这里有什么问题? Mouseup,单击都不会产生 console.log 事件。

   <select id='pageSelectDropdown'>
        <option value='Add New Page'>Add New Page</option>
        <option value='Great Page'>Great Page</option>
        <option value='Family Page'>Family Page</option>
      </select>

      <script type="text/javascript">
      opts = document.getElementsByTagName('option');
      console.log(opts)
      for (i = 0; i < opts.length; i++) {
        opts[i].addEventListener('click', ()=>{
          console.log('clicked')
        })
      }
      </script>

【问题讨论】:

  • but the onclick is null 使用addEventListener 添加事件侦听器不会更改使用.onclick =“添加”的事件侦听器 - 所以.onclick 为空是非常好的 - 事件侦听器应该无论如何都已正确添加
  • 顺便说一句,您只需设置selectList.options.length = 0即可删除所有选项。
  • 这是一个多选列表吗?如果没有,在我看来,将侦听器添加到选择本身并在处理程序中测试当前值会更容易。
  • 非常感谢您迄今为止的反馈!所以它实际上并没有在 eventlistener 回调中触发 console.log,所以它仍然以某种方式被破坏。这是一个单一的选择列表,但即使我重新选择了相同的选项,我也需要能够重新关注信息字段,这就是 onChange 侦听器不起作用的原因。真的很感谢这些信息,但对这些细节一无所知:)

标签: javascript html events addeventlistener


【解决方案1】:

不要依赖点击!改为听选择change。这样你就知道选择了什么真正的值了。

【讨论】:

    【解决方案2】:

    编辑:抱歉,我错过了你想调用该函数,即使用户选择了相同的选项。

    你可以看看这个,这确实有助于我回答你的问题:

    Run change event for select even when same option is reselected

    对于您的玩具示例,您可以这样做:

    var isopen = false;
    var sel = document.getElementById('pageSelectDropdown');
    sel.addEventListener('mouseup', () => {
      if (isopen) {
        console.log("changed to " + sel.value);
        isopen = false;
      } else {
        isopen = true;
      }
    });
    sel.addEventListener('blur', () => {
      isopen = false;
    });
    <select id='pageSelectDropdown'>
      <option value='Add New Page'>Add New Page</option>
      <option value='Great Page'>Great Page</option>
      <option value='Family Page'>Family Page</option>
    </select>

    我尝试了您的问题,结果如下:

    function updateSelectOptions(selectID){
        var isopen = false;
        var selectList = document.getElementById(selectID);
        while (selectList.length > 0) {
            selectList.remove(selectList.length -1);
        }
    
        // settingsNameArray is get from chrome.storage.local
        var settingsNameArray = ["Great Page", "Family Page", "Test Page", "fooo"];
        if (selectID === 'pageSelectDropdown') {
            settingsNameArray.unshift('Add New Page');
        }
    
        // selectedPage is get from chrome.storage.local
        var selectedPage = "Family Page";
        var selectedPageIndex = settingsNameArray.indexOf(selectedPage);
        // deleted the event handler for each option
        for (var i = 0; i < settingsNameArray.length; i++) {
            var option = document.createElement("option");
            option.setAttribute("value", i);
            option.setAttribute("class", 'optionClass');
            option.text = settingsNameArray[i];
            selectList.appendChild(option);
        }
        // add the event listener to the list
        selectList.addEventListener('mouseup', ()=>{
            if (isopen) {
                console.log("working! change to " + selectList.value + " : " + settingsNameArray[selectList.value]);
                document.getElementById('info').focus();
                // variable isopen automatically turn to false when blur
            } else {
                isopen = true;
            }
        });
        selectList.addEventListener('blur', ()=>{
            isopen = false;
        });
        selectList.value = selectedPageIndex;
    }
    <select id='pageSelectDropdown'>
        <option value='Add New Page'>Add New Page</option>
        <option value='Great Page'>Great Page</option>
        <option value='Family Page'>Family Page</option>
    </select>
    <br>
    <button onclick="updateSelectOptions('pageSelectDropdown');this.remove();">Call the function</button>
    <br>
    <textarea id="info"></textarea>

    其实这也适用于带字符串的选项值,可读性更强。

    function updateSelectOptions(selectID){
        var isopen = false;
        var selectList = document.getElementById(selectID);
        while (selectList.length > 0) {
            selectList.remove(selectList.length -1);
        }
    
        // settingsNameArray is get from chrome.storage.local
        var settingsNameArray = ["Great Page", "Family Page", "Test Page", "fooo"];
        if (selectID === 'pageSelectDropdown') {
            settingsNameArray.unshift('Add New Page');
        }
    
        // selectedPage is get from chrome.storage.local
        var selectedPage = "Family Page";
        // deleted the event handler for each option
        for (var i in settingsNameArray) {
            var option = document.createElement("option");
            option.setAttribute("value", settingsNameArray[i]);
            option.setAttribute("class", 'optionClass');
            option.text = settingsNameArray[i];
            selectList.appendChild(option);
        }
        // add the event listener to the list
        selectList.addEventListener('mouseup', ()=>{
            if (isopen) {
                console.log("working! change to " + selectList.value);
                document.getElementById('info').focus();
                // variable isopen automatically turn to false when blur
            } else {
                isopen = true;
            }
        });
        selectList.addEventListener('blur', ()=>{
            isopen = false;
        });
        selectList.value = selectedPage;
    }
    <select id='pageSelectDropdown'>
        <option value='Add New Page'>Add New Page</option>
        <option value='Great Page'>Great Page</option>
        <option value='Family Page'>Family Page</option>
    </select>
    <br>
    <button onclick="updateSelectOptions('pageSelectDropdown');this.remove();">Call the function</button>
    <br>
    <textarea id="info"></textarea>

    【讨论】:

    • 不幸的是,即使他们选择了相同的选项,我也需要运行回调
    • 由于某种原因,当我运行代码 sn-ps 时它的工作方式不一致
    • @Shinjitsu 你能提供更多细节吗?
    • 例如第一个,每隔一次被选中时只有console.log
    猜你喜欢
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多