DEV Community

Cover image for 🚨 Made a LIVE 2024 election counter! Enjoy
Asadbek Karimov
Asadbek Karimov

Posted on

🚨 Made a LIVE 2024 election counter! Enjoy

Live2024

Built a quick live 2024 Trump vs. Harrison counter. Pulling data from CNN’s live tracker into a simple, clean card. Most live trackers I found were cluttered with unnecessary components and text, so I created a streamlined version in just 5-10 minutes. Feel free to grab the code!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2024 US Election Counter</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        .card {
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            padding: 20px;
            text-align: center;
            max-width: 400px;
            width: 100%;
        }
        h1 {
            color: #333;
            font-size: 24px;
            margin-bottom: 10px;
        }
        p {
            color: #666;
            font-size: 14px;
            margin-bottom: 20px;
        }
        .counter-container {
            display: flex;
            justify-content: space-around;
        }
        .counter {
            text-align: center;
        }
        .counter h2 {
            font-size: 18px;
            margin-bottom: 10px;
        }
        .count {
            font-size: 36px;
            font-weight: bold;
            transition: all 0.5s ease;
        }
        .democrats {
            color: #0015bc;
        }
        .republicans {
            color: #ff0000;
        }
        .loading, .error {
            text-align: center;
            font-size: 18px;
            color: #666;
        }
        .error {
            color: #ff0000;
        }
        .vote-info {
            font-size: 14px;
            color: #555;
        }
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }

        .banner {
            position: fixed;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #f8f8f8;
            text-align: center;
            border-top: 1px solid #ddd;
            padding-top:6px;
            padding-bottom: 6px;
            font-size: x-large;
            font-weight: 500;
            color: #171717;
        }

        .banner a {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <div class="card">
        <h1>2024 US Election Counter</h1>
        <p>Live results updated every 10 seconds</p>
        <div id="content">
            <div class="loading">Loading...</div>
        </div>
    </div>


    <!-- Google tag (gtag.js) -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-W16Z0D8BJ7"></script>
    <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());

    gtag('config', 'G-W16Z0D8BJ7');
    </script>

    <script>
        const content = document.getElementById('content');

        function updateCounter(party, count, percentage, votes) {
            const countElement = document.getElementById(`${party}-count`);
            if (countElement) {
                countElement.textContent = count;
                document.getElementById(`${party}-percentage`).textContent = `${percentage}%`;
                document.getElementById(`${party}-votes`).textContent = `Votes: ${votes}`;
                countElement.style.animation = 'pulse 0.5s ease';
                setTimeout(() => {
                    countElement.style.animation = '';
                }, 500);
            }
        }

        function renderCounters(democratsCount, republicansCount, demPercentage, repPercentage, demVotes, repVotes) {
            content.innerHTML = `
                <div class="counter-container">
                    <div class="counter">
                        <h2 class="democrats">Democrats</h2>
                        <div id="democrats-count" class="count democrats">${democratsCount}</div>
                        <div id="democrats-percentage" class="vote-info">${demPercentage}%</div>
                        <div id="democrats-votes" class="vote-info">Votes: ${demVotes}</div>
                    </div>
                    <div class="counter">
                        <h2 class="republicans">Republicans</h2>
                        <div id="republicans-count" class="count republicans">${republicansCount}</div>
                        <div id="republicans-percentage" class="vote-info">${repPercentage}%</div>
                        <div id="republicans-votes" class="vote-info">Votes: ${repVotes}</div>
                    </div>
                </div>
            `;
        }

        async function fetchElectionData() {
            try {
                const response = await fetch('https://politics.api.cnn.io/results/bop/2024-PG-US.json', {
                    headers: {
                        'accept': '*/*',
                        'accept-language': 'en-US,en;q=0.9',
                        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
                        'x-api-key': 'TtGlrrOrcdJNvE5U9t4XulVZuwk68Ecru3UIgtnr'
                    }
                });

                if (!response.ok) {
                    throw new Error('Failed to fetch election data');
                }

                const data = await response.json();

                // Extract the relevant counts, percentages, and vote numbers
                const democratsData = data.meta.candidates.DEM;
                const republicansData = data.meta.candidates.REP;

                const democratsCount = democratsData.count;
                const republicansCount = republicansData.count;
                const democratsPercentage = democratsData.votePercentStr;
                const republicansPercentage = republicansData.votePercentStr;
                const democratsVotes = democratsData.voteStr;
                const republicansVotes = republicansData.voteStr;

                // Render the counters or update them if they already exist
                if (content.querySelector('.counter-container')) {
                    updateCounter('democrats', democratsCount, democratsPercentage, democratsVotes);
                    updateCounter('republicans', republicansCount, republicansPercentage, republicansVotes);
                } else {
                    renderCounters(democratsCount, republicansCount, democratsPercentage, republicansPercentage, democratsVotes, republicansVotes);
                }
            } catch (error) {
                console.error('Error:', error);
                content.innerHTML = '<div class="error">Error fetching election data</div>';
            }
        }

        function startPolling() {
            fetchElectionData(); // Initial fetch on load
            setInterval(fetchElectionData, 10000); // Poll every 10 seconds
        }

        startPolling();
    </script>

    <div class="banner">
        Sponsored by <a href="https://mylinx.cc/" target="_blank">Mylinx</a>
    </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay