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

jQuery图片Select组件问题:两个Select事件无法独立触发

修复jQuery多图片Select的事件分离问题

问题根源

  1. 全局数组未重置:langArray定义在全局,遍历第二个.box时会继续累加第一个的选项,导致第二个下拉框内容重复
  2. 全局选择器操作:事件处理中使用$(".btn-select")、$(".b")这类全局选择器,点击时会操作所有匹配元素,导致两个下拉框同时展开/内容同步
  3. 重复ID使用:HTML中两个<ul>都用了id="a",ID在页面中必须唯一,会导致DOM选择混乱

修复方案

  1. 将langArray移到.box的遍历循环内部,每次循环初始化空数组,确保每个下拉框的选项独立
  2. 事件处理时通过$(this)定位当前操作的.box容器,只操作容器内的元素,避免影响其他下拉框
  3. 将重复的IDa改为classa,保证DOM结构合法性

修复后的完整代码

HTML

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div class="box" id="one">
  <select class="vodiapicker">
    <option>Select one</option>
    <option value="en" class="test" data-thumbnail="images/3.png">
      English
    </option>
    <option value="au" data-thumbnail="images/3.png">Engllish (AU)</option>
  </select>

  <div class="lang-select">
    <button class="btn-select" value=""></button>
    <div class="b">
      <ul class="a"></ul>
    </div>
  </div>
</div>
<div class="box" id="two">
  <select class="vodiapicker">
    <option>Select one</option>
    <option value="en" class="test" data-thumbnail="images/3.png">
      french
    </option>
    <option value="au" data-thumbnail="images/3.png">french F</option>
  </select>

  <div class="lang-select">
    <button class="btn-select" value=""></button>
    <div class="b">
      <ul class="a"></ul>
    </div>
  </div>
</div>

CSS

.vodiapicker {
  display: none;
}

.a {
  padding-left: 0px;
}

.a img,
.btn-select img {
  width: 18px;
}

.a li {
  list-style: none;
  padding-top: 5px;
  padding-bottom: 5px;
}

.a li:hover {
  background-color: #f4f3f3;
}

.a li img {
  margin: 5px;
}

.a li span,
.btn-select li span {
  margin-left: 30px;
}

/* item list */

.b {
  display: none;
  width: 100%;
  max-width: 350px;
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 5px;
}

.open {
  display: block !important;
}

.btn-select {
  margin-top: 10px;
  width: 100%;
  max-width: 350px;
  height: 34px;
  border-radius: 5px;
  background-color: #fff;
  border: 1px solid #ccc;
}

.btn-select li {
  list-style: none;
  float: left;
  padding-bottom: 0px;
}

.btn-select:hover li {
  margin-left: 0px;
}

.btn-select:hover {
  background-color: #f4f3f3;
  border: 1px solid transparent;
  box-shadow: inset 0 0px 0px 1px #ccc;
}

.btn-select:focus {
  outline: none;
}

.lang-select {
  margin-left: 50px;
}

JavaScript

$(".box").each(function () {
  // 每个box单独维护自己的选项数组
  var langArray = [];
  var $box = $(this);
  
  $box.find(".vodiapicker option").each(function () {
    var img = $(this).attr("data-thumbnail");
    var text = this.innerText;
    var value = $(this).val();
    var item =
      '<li><img src="' +
      img +
      '" alt="" value="' +
      value +
      '"/><span>' +
      text +
      "</span></li>";
    langArray.push(item);
  });

  $box.find(".a").html(langArray);

  // 设置当前box的按钮初始值
  $box.find(".btn-select").html(langArray[0]);
  $box.find(".btn-select").attr("value", "en");

  // 检查本地存储,仅初始化当前box的语言
  var sessionLang = localStorage.getItem("lang-" + $box.attr("id"));
  if (sessionLang) {
    // 找到对应value的选项
    var targetItem = langArray.find(item => item.includes(`value="${sessionLang}"`));
    if (targetItem) {
      $box.find(".btn-select").html(targetItem);
      $box.find(".btn-select").attr("value", sessionLang);
    }
  }
});

// 事件委托绑定li点击事件,限定在.box范围内
$(document).on("click", ".box .a li", function () {
  var $li = $(this);
  var $box = $li.closest(".box");
  var img = $li.find("img").attr("src");
  var value = $li.find("img").attr("value");
  var text = $li.find("span").text(); // 直接取span文本避免包含img内容
  var item =
    '<li><img src="' + img + '" alt="" /><span>' + text + "</span></li>";
  
  // 仅更新当前box的按钮
  $box.find(".btn-select").html(item);
  $box.find(".btn-select").attr("value", value);
  $box.find(".b").toggle();
  
  // 保存到本地存储,区分不同box
  localStorage.setItem("lang-" + $box.attr("id"), value);
});

// 按钮点击仅切换当前box的下拉框
$(document).on("click", ".box .btn-select", function () {
  var $box = $(this).closest(".box");
  // 关闭其他box的下拉框
  $(".box").not($box).find(".b").hide();
  // 切换当前box的下拉框
  $box.find(".b").toggle();
});

额外优化说明

  • 本地存储增加了box的ID作为前缀,避免两个下拉框的语言设置互相覆盖
  • 点击按钮时自动关闭其他下拉框,提升交互体验
  • 取文本时直接用span的内容,避免包含img的空白字符

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:24:23