代码之家  ›  专栏  ›  技术社区  ›  new221

动态添加<option>元素来选择标签会破坏其功能

  •  0
  • new221  · 技术社区  · 6 月前

    我试图根据某些条件动态地向select标签添加选项

    https://jsfiddle.net/kvnhdpyg/

    document.getElementById('metodode').addEventListener('click', function(e) {
    
      this.innerHTML = '';
      const elemento = document.createElement('option');
      elemento.text = 'Escolha uma opçao';
      elemento.value = '';
      elemento.disabled = true;
      elemento.selected = true;
      this.appendChild(elemento);
    
      for (let i = 0; i < 5; i++) {
    
        const elemento = document.createElement('option');
        elemento.text = "test123"
    
        this.appendChild(elemento);
      }
    });
    <select id="metodode" style="cursor:pointer;">
      <option id="first" value="" disabled selected>Escolha uma opçao</option>
    </select>

    这是它的简写版本,动态添加选项标签进行选择会破坏它的功能,点击动态选项标签不会像普通选项标签那样将其文本放入选择标签中

    我也尝试过添加事件监听器,但不起作用,我可以 console.log() 但没有点击

    1 回复  |  直到 6 月前
        1
  •  2
  •   Diego D    6 月前

    这是因为通过使用 click 事件处理程序,事件发生两次:

    • 当你第一次点击下拉菜单选择一个选项时
    • 当你选择一个选项时

    第二次,当你应该选择一个选项时,它会破坏选项列表,从而重置情况。为什么?因为所选选项传递的信息是 selected 但你在设定状态后不久就摧毁并重建了这些。

    您可以通过在事件处理程序中添加console.log来验证此行为。

    现在值得说的是,拥有这样的策略是一种糟糕的做法,但为了找到一种解决方法,如果你转而依赖 mousedown 事件,它只会在实际按下下拉菜单上的鼠标按钮时发生。

    编辑 公平地说,我意识到,如果你在选择了一个选项后点击下拉菜单,重置所选选项时,同样的恶劣行为也会再次发生。尽管这里的主要重点是找到这种奇怪行为背后的原因,但我修改了代码片段,以解决我以前没有考虑过的这种副作用。

    document.getElementById('metodode')
      .addEventListener('mousedown', function(e) {
    
        //keep track of the currently selected option
        const currentValue = this.value;
    
        this.innerHTML = '';
        const elemento = document.createElement('option');
        elemento.text = 'Escolha uma opçao';
        elemento.value = '';
        elemento.disabled = true;
        elemento.selected = true;
        this.appendChild(elemento);
    
        for (let i = 0; i < 5; i++) {
          const elemento = document.createElement('option');
          elemento.text = "test123-" + i;
          elemento.value = i;
          this.appendChild(elemento);
        }
    
        //restore the previously selected option (if it exists)
        //I'm using a general approach just to fit with
        //further scenarios beyond this simple demo
        const options = [...this.options];
        const matchingOption =
          options.find(opt => opt.value === currentValue);
        if (matchingOption) {
          matchingOption.selected = true;
        }
      
    });
    <select id="metodode" style="cursor:pointer;">
      <option id="first" value="" disabled selected>
        Escolha uma opçao
      </option>
    </select>