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

jQuery下拉组件迁移至原生JS后点击选项下拉框立即关闭问题及is/has方法原生替代方案咨询

解决下拉组件迁移到原生JS后选中选项立即关闭的问题

我明白你的问题了——原来的jQuery代码通过is()和has()判断点击事件是否来自下拉相关元素(或其子元素),如果是就阻止后续的关闭逻辑;但你写的原生JS代码只判断了点击目标是不是直接匹配选择器的元素,没考虑子元素的情况,所以点击下拉选项(子元素)的时候,就触发了关闭逻辑。

先拆解一下原jQuery代码的作用:

if($('*[data-toggle], *[data-totoggle]').is(e.target) || $('*[data-toggle], *[data-totoggle]').has(e.target).length){ return false; }

这行代码做了两件事:

  • 判断点击的目标e.target是否本身就是带有data-toggle或data-totoggle属性的元素
  • 或者,点击的目标是否是这些元素的子元素(has(e.target).length大于0意味着存在这样的父元素)
    只要满足其中一个条件,就返回false,不执行后面的关闭下拉逻辑。

原生JS的等效实现

你可以用原生的closest()方法来同时覆盖这两种情况:e.target.closest('*[data-toggle], *[data-totoggle]')会返回匹配选择器的最近祖先元素(包括元素本身),如果存在这样的元素,就说明点击事件来自下拉相关元素或其子元素,此时应该阻止关闭逻辑。

修改你的mouseup事件中的判断代码:

// 替换原来的if判断
const isToggleElement = e.target.closest('*[data-toggle], *[data-totoggle]') !== null;
if (isToggleElement) {
  return false;
}

另外,你的代码里还有一些jQuery残留需要替换,避免其他潜在问题:

  • element.html() 要改成原生的 element.innerHTML 或者 element.textContent(如果只是操作纯文本,用后者更安全)
  • $('*[data-toslidetoggle]').slideUp() 需要用原生JS实现滑上效果,比如通过CSS过渡动画修改元素的height、opacity属性,或者先设置max-height再过渡

修改后的完整mouseup事件代码

document.addEventListener('mouseup', function (e) {
  // 判断点击是否来自下拉相关元素或其子元素
  const isToggleElement = e.target.closest('*[data-toggle], *[data-totoggle]') !== null;
  if (isToggleElement) {
    return false;
  }
  document.querySelectorAll('*[data-toggle], *[data-totoggle]').forEach(function (element) {
    if (!element.classList.contains('onlyClick')) {
      element.classList.remove('active')
    }
  })

  // 同样处理slideToggle的部分
  const isSlideToggleElement = e.target.closest('*[data-slidetoggle], *[data-toslidetoggle]') !== null;
  if (isSlideToggleElement) {
    return false;
  }
  document.querySelectorAll('*[data-slidetoggle]').forEach(function (element) {
    if (!element.classList.contains('onlyClick')) {
      element.classList.remove('active');
      // 替换jQuery的slideUp,这里用简单的过渡动画示例
      document.querySelectorAll('*[data-toslidetoggle]').forEach(el => {
        el.style.transition = 'max-height 0.2s ease-out';
        el.style.maxHeight = '0';
        el.style.overflow = 'hidden';
      });
    }
  })
});

这样修改后,点击下拉选项(子元素)时,closest()会找到对应的父级下拉元素,从而返回false,阻止后续的关闭逻辑,下拉框就不会在选中选项后立刻关闭了。

内容的提问来源于stack exchange,提问作者niels van hoof

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:37:34