You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套<select>的<option>鼠标悬停文本切换失效问题求助

嵌套Select组件Option悬停文本切换失效:问题排查与修复方案

问题背景

需求:嵌套的<select id="typeSelect">组件,默认其<option>文本取自ctisData;鼠标悬停在这些option上时,切换为ctisData2中对应内容;移出时恢复原文本。现有代码添加鼠标事件后未生效。

原有核心HTML代码:

<th><form class='lm_search_box'>
    <div style='position: relative;'>
        <select id='optSelect' class='lm_search_input' style='font-family: "Roboto"; font-size: 15px;'>
            <option value=''>Select</option>
            <option value='Option1'>Option1</option>
            <option value='Option2'>Option2</option>
            <option value='Option3'>Option3</option>
        </select>
        <select id='typeSelect' class='lm_search_input' style='font-family: "Roboto"; display: none;'>
            <option value=''>Select</option>
        </select>
    </div>
</form>
</th>

原有核心JavaScript代码:

const ctisData = {
  'Option1': ['Op11', 'Op12', 'Op13'],
  'Option2': ['Op21', 'Op22', 'Op23'],
  'Option3': ['Op31', 'Op32', 'Op33']
};

const ctisData2 = {
  'Option1': ['Option11', 'Option12', 'Option13'],
  'Option2': ['Option21', 'Option22', 'Option23'],
  'Option3': ['Option31', 'Option32', 'Option33']
};

function do_select(select, options) {
  select.innerHTML = '<option>Select</option>';
  options.forEach(function(value) {
    var z = document.createElement('option');
    z.setAttribute('value', value);
    z.innerText = value;
    select.appendChild(z);
  });
}

var sel_category = document.getElementById('optSelect');
var sel_type = document.getElementById('typeSelect');

sel_category.addEventListener('change', function() {
  var selectedCategory = sel_category.value;
  if (selectedCategory !== '') {
    sel_type.style.display = 'block';
    do_select(sel_type, ctisData[selectedCategory]);
  } else {
    sel_type.style.display = 'none';
  }
});

sel_type.addEventListener('change', function() {
  var selectedValue = sel_type.value;
  if (selectedValue !== '') {
    window.location.href = 'index.php?_search=' + selectedValue + '&action=search';
  }
});

添加的无效事件代码:

var options = document.querySelectorAll('#optSelect option');
options.forEach(option => {
    option.addEventListener('mouseover', function() {
        var category = sel_category.value;
        var index = Array.from(options).indexOf(this);
        var newOptionText = ctisData2[category][index];
        this.innerText = newOptionText;
    });
    option.addEventListener('mouseout', function() {
        var category = sel_category.value;
        var index = Array.from(options).indexOf(this);
        var originalOptionText = ctisData[category][index];
        this.innerText = originalOptionText;
    });
});

问题原因

  1. 事件绑定对象错误:代码给#optSelect的option绑定事件,但需求是修改嵌套的#typeSelect的option文本,对象完全不匹配。
  2. 索引计算错误:#optSelect和#typeSelect的option都包含默认的<option>Select</option>,直接用元素索引取ctisData数组会导致越界或取错值。
  3. 动态元素未绑定事件:#typeSelect的option是通过do_select动态生成的,页面加载时的querySelectorAll无法获取后续生成的元素,新添加的option没有事件监听。

修复方案

不需要额外CSS支持,仅需修改JavaScript代码,核心调整如下:

  • 在do_select函数生成option时直接绑定鼠标事件,通过自定义属性保存原始文本、数据索引和所属分类。
  • 修正索引逻辑,跳过默认的Select选项,用数据数组的原生索引匹配内容。

修改后的完整JavaScript代码:

const ctisData = {
  'Option1': ['Op11', 'Op12', 'Op13'],
  'Option2': ['Op21', 'Op22', 'Op23'],
  'Option3': ['Op31', 'Op32', 'Op33']
};

const ctisData2 = {
  'Option1': ['Option11', 'Option12', 'Option13'],
  'Option2': ['Option21', 'Option22', 'Option23'],
  'Option3': ['Option31', 'Option32', 'Option33']
};

function do_select(select, options, category) {
  select.innerHTML = '<option>Select</option>';
  options.forEach(function(value, index) {
    var z = document.createElement('option');
    z.setAttribute('value', value);
    z.innerText = value;
    // 保存原始文本、数据索引和所属分类
    z.dataset.originalText = value;
    z.dataset.dataIndex = index;
    z.dataset.category = category;
    
    // 绑定鼠标悬停事件
    z.addEventListener('mouseover', function() {
      const dataIndex = parseInt(this.dataset.dataIndex);
      const targetCategory = this.dataset.category;
      this.innerText = ctisData2[targetCategory][dataIndex];
    });
    
    // 绑定鼠标移出事件
    z.addEventListener('mouseout', function() {
      this.innerText = this.dataset.originalText;
    });
    
    select.appendChild(z);
  });
}

var sel_category = document.getElementById('optSelect');
var sel_type = document.getElementById('typeSelect');

sel_category.addEventListener('change', function() {
  var selectedCategory = sel_category.value;
  if (selectedCategory !== '') {
    sel_type.style.display = 'block';
    // 调用时传入当前选中的分类
    do_select(sel_type, ctisData[selectedCategory], selectedCategory);
  } else {
    sel_type.style.display = 'none';
  }
});

sel_type.addEventListener('change', function() {
  var selectedValue = sel_type.value;
  if (selectedValue !== '') {
    window.location.href = 'index.php?_search=' + selectedValue + '&action=search';
  }
});

代码说明

  • 给do_select新增category参数,避免事件触发时重复获取分类值。
  • 用data-*属性存储关键数据,确保事件触发时能准确匹配ctisData2中的内容。
  • 动态生成option时直接绑定事件,保证所有新增元素都有事件监听。
  • 移除原无效的事件绑定代码,无需单独处理页面初始元素。

内容的提问来源于stack exchange,提问作者user221117

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:28:10