헤더의 카운트다운 스크립트가 아바타 드롭다운을 중복으로 표시하는 이유는?

I have the following script running in my header, and it’s rendering just fine.

But when I navigate to a topic, the avatar dropdown replicates like this:

Hoping it’s a simple fix, but maybe I’m trying to make Discourse do too much w/ a component.

<script>
document.addEventListener('DOMContentLoaded', function() {
    // Create Countdown HTML with Styling
    var countdownHtml = `
        <div id="countdown-banner" style="position: relative; display: inline-block; margin-left: 20px; vertical-align: middle;">
            <span id="background-text" style="opacity: 0.2; color: gray; font-size: 4.5em; position: absolute; left: 0; top: -31px; z-index: 1;">
                DET vs. DAL <i class="fas fa-football-ball"></i>
            </span>
            <div id="foreground-text" style="color: white; position: relative; z-index: 2; display: flex; align-items: center;">
                <span id="countdown-container" style="background-color: #0076B6; padding: 5px 10px; border-radius: 5px; margin-right: 10px;">
                    Lions at Cowboys: <span id="countdown" style="font-family: 'LCD', 'Courier New', monospace;"></span>
                </span>
                <a href="https://thedenforum.com/t/official-lions-vs-cowboys-game-day-thread-2023/30290" style="background-color: #0076B6; color: white; padding: 5px 10px; border-radius: 5px; text-decoration: none;">
                    Game Thread
                </a>
            </div>
        </div>`;

    // Insert the Countdown Banner next to the logo
    var headerLogo = document.querySelector('.d-header .title');
    if (headerLogo) {
        headerLogo.insertAdjacentHTML('afterend', countdownHtml);
    } else {
        console.error("Header logo not found");
    }

    // Countdown Functionality
    const eventTime = new Date('December 30, 2023 20:00:00 GMT-0400').getTime();
    const countdownElement = document.getElementById('countdown');

    if (!countdownElement) {
        console.error("Countdown element not found");
        return;
    }

    function updateCountdown() {
        const now = new Date().getTime();
        const distance = eventTime - now;

        if (distance < 0) {
            countdownElement.innerHTML = "The Game Has started!";
            clearInterval(interval);
            return;
        }

        const days = Math.floor(distance / (1000 * 60 * 60 * 24));
        const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        const seconds = Math.floor((distance % (1000 * 60)) / 1000);

        countdownElement.innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
    }

    var interval = setInterval(updateCountdown, 1000);
});
</script>

Solved! I fixed it using api.onPageChange(() => { if anyone else tries getting too fancy for their own good and encounters the same.

꽤 멋지네요.

이 배너는 게임이 시작될 때까지 카운트다운을 하는 건가요? (스포츠)

상업용 사이트나 다른 용도로 꽤 멋진 Customization > Theme component 시작점이 될 수 있겠네요. 런칭이나 다가오는 세일을 위한 카운트다운으로 사용할 수도 있고요.

수정된 코드를 올려주실 수 있을까요?

I gave up on it because it renders the avatar menu unclickable. I tried everything to fix with no luck, so gave up, otherwise I’d submit it!

Perhaps you could release it as is, with a disclaimer on it about the bugs it causes to others could potentially try to fix it?

Might be an idea to try maybe in header?

Here’s the code for all who have asked.

<script type="text/discourse-plugin" version="0.8">
    api.onPageChange(() => {
        // Ensure the banner is only added once
        if (document.getElementById('countdown-banner')) return;

        // Create the countdown banner
        const countdownBanner = document.createElement('div');
        countdownBanner.id = 'countdown-banner';
        countdownBanner.style.cssText = 'position: relative; display: inline-block; margin-left: 20px; vertical-align: middle;';
        countdownBanner.innerHTML = `
            <span id="background-text" style="opacity: 0.2; color: gray; font-size: 4.5em; position: absolute; left: 0; top: -31px; z-index: 1;">
                DET vs. DAL <i class="fas fa-football-ball"></i>
            </span>
            <div id="foreground-text" style="color: white; position: relative; z-index: 2; display: flex; align-items: center;">
                <span id="countdown-container" style="background-color: #0076B6; padding: 5px 10px; border-radius: 5px; margin-right: 10px;">
                    Lions at Cowboys: <span id="countdown" style="font-family: 'LCD', 'Courier New', monospace;"></span>
                </span>
                <a href="[URL]" style="background-color: #0076B6; color: white; padding: 5px 10px; border-radius: 5px; text-decoration: none;">
                    Game Thread
                </a>
            </div>
        `;

        // Find the header logo and insert the countdown banner
        const headerLogo = document.querySelector('.d-header .title');
        if (headerLogo) {
            headerLogo.insertAdjacentElement('afterend', countdownBanner);
        }

        // Initialize the countdown
        const eventTime = new Date('December 30, 2024 20:00:00 GMT-0400').getTime();
        const countdownElement = document.getElementById('countdown');
        setInterval(() => {
            const now = new Date().getTime();
            const distance = eventTime - now;

            if (!countdownElement) return;

            if (distance < 0) {
                countdownElement.innerHTML = "The Game Has started!";
                return;
            }

            const days = Math.floor(distance / (1000 * 60 * 60 * 24));
            const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
            const seconds = Math.floor((distance % (1000 * 60)) / 1000);

            countdownElement.innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
        }, 1000);
    });
</script>

CSS …

#countdown-container, #countdown-banner a {
    background-color: #0076B6; /* Solid background color */
    opacity: 0.8; /* Adjust transparency */
    /* Other styling... */
}


#countdown-container {
    background-color: rgba(0, 118, 182, 0.3); /* Slightly transparent background */
    padding: 5px 10px;
    border-radius: 5px;
    margin-right: 10px;
}

#countdown-banner a {
    background-color: rgba(0, 118, 182, 0.3); /* Slightly transparent background */
    color: white;
    padding: 5px 10px;
    border-radius: 5px;
    text-decoration: none;
    transition: background-color 0.3s;
}

#countdown-banner a:hover {
    background-color: rgba(0, 95, 138, 0.3); /* Slightly darker on hover with transparency */
}


#countdown-banner {
    font-family: Arial, sans-serif;
    position: relative;
    display: inline-block;
    margin-left: 20px;
    vertical-align: middle;
}

#background-text {
    font-family: 'Impact', sans-serif;
    font-size: 5em; /* Size of the text */
    color: gray; /* Changed to gray */
    opacity: 0.5; /* Adjust opacity for visibility */
    position: absolute;
    left: 0;
    top: -30px; /* More significantly shifted up */
    z-index: 1;
    font-weight: bold; /* Bold font */
}

#foreground-text {
    color: white;
    position: relative;
    z-index: 2;
    padding-left: 140px; /* Adjust based on actual layout */
}

#countdown {
    font-family: 'LCD', 'Courier New', monospace;
    font-size: 1.2em;
}

Please note I never did get the avatar menu to become clickable. :confused: … if you can correct and share, that’d be amazing!