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

如何实现Bootstrap Popover内容动态更新?附代码求助

问题修复方案:Bootstrap Popover 动态内容更新异常

Hey there, let's dig into your code and fix those issues with the popover not updating correctly after clicking the purchase button! I spotted a few key problems that are causing the unexpected behavior:


1. 数组被错误覆盖,导致历史数据丢失

In the else branch of your product_buy_now function, you're using news_price_data = [20]; which completely replaces the entire array instead of adding a new element. This wipes out all previous price data, making your total price calculations wrong. Switch it to news_price_data.push(20); to preserve existing data.

2. Bootstrap Popover 未刷新更新后的内容

Once you initialize a Bootstrap popover, just updating the title and data-content attributes won't refresh the popover. You need to destroy the old instance and re-initialize it to pick up the new content.

3. 全局元素重复追加内容,导致叠加混乱

Your poH and poC elements are defined in the global scope, so every time inbox_open runs, new content gets appended to the same elements. This causes duplicate headers and content after multiple purchases. Move these element creations inside the inbox_open function to start fresh each time.

4. 重复绑定事件,导致点击多次触发

You're binding click events to the popover header buttons every time the popover shows up. This means after multiple opens, each button has multiple click handlers attached, leading to unexpected behavior. We'll fix this by binding events only once and using proper event cleanup.


修复后的完整代码

<!-- HTML -->
<button class="btn btn-sm btn-danger" style="margin: 40px 0 0 0;" onclick="product_buy_now()">Click Me First</button>
<button id="inbox" class="btn btn-primary btn-sm" style="margin: 40px 0 0 400px;" data-toggle="popover" data-placement="left" data-html="true" title="" data-content="">inbox</button>

<!-- Script -->
<script>
// inbox core references
var inbox = document.getElementById("inbox");
var news_from_to = [];
var number_of_news = [];
var news_price_data = [];

// inbox.open function - now creates fresh containers each call
function inbox_open(news_from_to, number_of_news, news_price_data) {
    console.log("Opening Executed!");
    console.log("\nCraft Data:");
    console.log(news_from_to);
    console.log(number_of_news);
    console.log(news_price_data);
    console.log("");

    // Create NEW header/content containers every time to avoid duplication
    var poH = document.createElement("span");
    var poC = document.createElement("span");

    for(var i = 0; i < news_from_to.length; i++) {
        // Create individual header/content components
        var b = document.createElement("button");
        var c = document.createElement("span");
        b.innerHTML = (i + 1);
        b.className = "poH";
        c.className = "poC";
        c.style = "display: none;";

        // Calculate total price for the current purchase batch
        var news_price_of_items = 0;
        for(var j = news_from_to[i]; j < (news_from_to[i] + number_of_news[i]); j++) {
            news_price_of_items += news_price_data[j];
        }

        // Populate content with purchase details
        c.innerHTML = "You Bought: <br />"+ number_of_news[i]+ " items <br />"+ "for $"+ news_price_of_items;

        // Add to popover containers
        poH.appendChild(b);
        poC.appendChild(c);
    }

    // Update popover attributes
    inbox.setAttribute("title", poH.innerHTML);
    inbox.setAttribute("data-content", poC.innerHTML);
    
    // Refresh Bootstrap popover: destroy old instance, re-initialize
    $('[data-toggle="popover"]').popover('dispose');
    $('[data-toggle="popover"]').popover();

    console.log("Craft as Crafted:")
    console.log(poH.innerHTML);
    console.log(poC.innerHTML);
}

// Initialize Bootstrap popover on page load
$(document).ready(function() {
    $('[data-toggle="popover"]').popover();

    // Handle popover shown event - bind events only once with cleanup
    $('#inbox').on('shown.bs.popover', function () {
        var poHs = document.getElementsByClassName("poH");
        var poCs = document.getElementsByClassName("poC");
        
        // Unbind existing click handlers before adding new ones
        for(var i = 0; i < poHs.length; i++) {
            poHs[i].removeEventListener('click', window['popoverHandler_' + i]);
            window['popoverHandler_' + i] = popoverClickHandler(i, poHs, poCs);
        }

        // Set initial active state for first item
        poHs[0].className += " seen active";
        poCs[0].style = "display: block;";
    });
});

// Reusable popover click handler - stored globally for easy unbinding
function popoverClickHandler(index, poHs, poCs) {
    var handler = function() {
        // Reset all items to inactive/hidden
        for(var j = 0; j < poHs.length; j++) {
            poHs[j].className = poHs[j].className.replace(" active", "");
        }
        for(var j = 0; j < poCs.length; j++) {
            poCs[j].style = "display: none;";
        }
        // Activate current item
        this.className += " seen active";
        poCs[index].style = "display: block;";
    };
    poHs[index].addEventListener('click', handler);
    return handler;
}

/* PRODUCT BUY NOW FUNCTIONALITY */
var now_cart_item = [];
var now_cart_in_item = [];

function product_buy_now() {
    // Update inbox data based on existing purchases
    if(news_from_to.length == 0) {
        console.log("if branch:\n");
        news_from_to = [0];
        number_of_news = [1];
        news_price_data = [10]; // Replace with your actual product price logic
        inbox_open(news_from_to, number_of_news, news_price_data);
    } else {
        console.log("else branch:\n");
        news_from_to.push(news_price_data.length);
        number_of_news.push(1);
        news_price_data.push(20); // Fixed: push instead of overwrite array
        inbox_open(news_from_to, number_of_news, news_price_data);
    }

    // Clear cart for next purchase
    now_cart_item = [];
    now_cart_in_item = [];
}
</script>

关键修复点说明

  • Preserve Purchase Data: Using push() instead of overwriting the price array keeps all historical purchase records intact.
  • Fresh Popover Containers: Creating new poH and poC elements each time inbox_open runs prevents content duplication.
  • Popover Refresh: Destroying and re-initializing the popover ensures the updated title/content is displayed.
  • Clean Event Binding: Storing handlers globally and unbinding before re-binding avoids multiple click triggers.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:38