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

Bootstrap Popover首次触发后无法再次弹出的问题求助

问题描述

我初步调研后确认这是真实存在的问题,但还没确定解决方案。

复现步骤

  • 在第一个输入框输入“0”
  • 接下来两个输入框都输入“2”(或任意相同数字)
  • 点击按钮,会弹出提示为“你选择了0,该值不能为0”的气泡弹窗(popover)
  • 将input-a中的“0”改为任意非零数字
  • 再次点击按钮——此时无任何反应

预期行为:触发下一个if语句,提示b和c不能相同。

疑问

  1. 为何会出现这种情况?
  2. 如何实现点击按钮关闭弹窗后,再次点击按钮能正常弹出下一个提示弹窗?

相关代码

JavaScript代码

document.getElementById("submit").addEventListener("click", calc);

function calc() {
  let a = parseFloat(document.getElementById("a").value);
  let b = parseFloat(document.getElementById("b").value);
  let c = parseFloat(document.getElementById("c").value);
  let output = document.getElementById("output");

  if (a === 0) {
    $(this).popover({
      placement: "bottom",
      content: '<textarea class="popover-textarea"></textarea>',
      template: '<div class="popover"><div class="arrow"></div>' +
        '<div class="row"><div class="col-3 my-auto">' +
        '</div><div class="popover-content col-9">You have chosen 0, this needs to be non-zero' +
        "</div></div>",
    });
    $(this).popover("show");
    $(this).click(function() {
      $(this).popover("hide");
    });
    return false;
  } else if (b === c) {
    $(this).popover({
      placement: "bottom",
      content: '<textarea class="popover-textarea"></textarea>',
      template: '<div class="popover"><div class="arrow"></div>' +
        '<div class="row"><div class="col-3 my-auto">' +
        '</div><div class="popover-content col-9">You have chosen b and c to be the same, they need to be different' +
        "</div></div>",
    });
    $(this).popover("show");
    $(this).click(function() {
      $(this).popover("hide");
    });
    return false;
  }
}

HTML代码

<form>
  <input type="number" id="a">
  <input type="number" id="b">
  <input type="number" id="c">
  <button type="button" id="submit">Hit me</button>
</form>
<p id="output"></p>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

问题解答

1. 问题原因

  • 重复绑定点击事件:每次执行calc函数时,都会给按钮新增一个click事件用于隐藏弹窗。第一次点击触发a===0逻辑后,按钮上绑定了隐藏事件;第二次点击时,这个隐藏事件会先执行,随后才会触发calc,但此时弹窗已被隐藏,且Bootstrap不会重复初始化已存在的Popover实例,导致第二个条件的弹窗无法显示。
  • Popover实例未更新:Bootstrap的Popover组件初始化后,直接调用popover()修改配置不会生效,因为组件实例已存在,必须先销毁旧实例才能重新配置。

2. 解决方案

优化后的代码

document.getElementById("submit").addEventListener("click", calc);
const $submitBtn = $("#submit");
// 定义弹窗模板,用占位符替换提示内容
const baseTemplate = '<div class="popover"><div class="arrow"></div>' +
  '<div class="row"><div class="col-3 my-auto"></div>' +
  '<div class="popover-content col-9">{{msg}}</div></div>';

// 初始化Popover,设置手动触发
$submitBtn.popover({
  placement: "bottom",
  content: '<textarea class="popover-textarea"></textarea>',
  template: baseTemplate.replace('{{msg}}', ''),
  trigger: 'manual'
});

// 仅绑定一次弹窗隐藏事件
$submitBtn.on('click', function(e) {
  const popoverInstance = $submitBtn.data('bs.popover');
  if (popoverInstance && popoverInstance._isShown) {
    $submitBtn.popover('hide');
    e.stopImmediatePropagation(); // 阻止触发calc函数
  }
});

function calc() {
  const a = parseFloat(document.getElementById("a").value);
  const b = parseFloat(document.getElementById("b").value);
  const c = parseFloat(document.getElementById("c").value);

  if (a === 0) {
    // 销毁旧实例,重新配置弹窗内容
    $submitBtn.popover('dispose');
    $submitBtn.popover({
      placement: "bottom",
      content: '<textarea class="popover-textarea"></textarea>',
      template: baseTemplate.replace('{{msg}}', '你选择了0,该值不能为0'),
      trigger: 'manual'
    });
    $submitBtn.popover("show");
    return;
  } else if (b === c) {
    $submitBtn.popover('dispose');
    $submitBtn.popover({
      placement: "bottom",
      content: '<textarea class="popover-textarea"></textarea>',
      template: baseTemplate.replace('{{msg}}', '你选择的b和c相同,它们必须不同'),
      trigger: 'manual'
    });
    $submitBtn.popover("show");
    return;
  }
}

核心优化点

  • 仅绑定一次弹窗隐藏事件,避免重复绑定导致的事件冲突
  • 使用trigger: 'manual'手动控制弹窗显示/隐藏,规避Bootstrap默认触发逻辑的干扰
  • 切换弹窗内容时,先销毁旧的Popover实例,再重新初始化新配置的实例,确保内容更新生效
  • 点击事件中判断弹窗状态:若弹窗正在显示则隐藏并阻止执行校验逻辑,否则正常执行校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:25:33