首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 實作網站「頂/踩」投票功能:前端完整代碼 (HTML/CSS/JS)

     編輯:PHP 相關知識

PHP 實作網站「頂/踩」投票功能:前端完整代碼 (HTML/CSS/JS)

文章、評論、產品常需「讚/踩」互動。本文提供完整前端實作 (HTML 結構、CSS 樣式、jQuery AJAX 互動),後端只需依規範回傳 success/done/error 即可串接,支援防重複投票、狀態鎖定、用戶提示。

1. HTML 結構

<div id="vote" data-id="<?php echo $articleId; ?>">
    <span id="dig" class="vote-btn">
        <span class="vote-num"><?php echo $digCount; ?></span>
    </span>
    <span id="bury" class="vote-btn">
        <span class="vote-num"><?php echo $buryCount; ?></span>
    </span>
</div>

data-id 為文章唯一識別碼,.vote-num 顯示當前計數。

2. CSS 樣式 (含圖片精靈建議)

#vote {
    text-align: center;
    margin: 20px 0;
}
.vote-btn {
    display: inline-block;
    width: 60px;
    height: 54px;
    margin: 0 20px;
    cursor: pointer;
    background-repeat: no-repeat;
    background-position: center top;
    transition: opacity 0.2s;
}
.vote-btn:hover { opacity: 0.8; }
.vote-btn.disabled { cursor: not-allowed; opacity: 0.5; }

#dig { background-image: url("/static/images/dig.png"); }
#bury { background-image: url("/static/images/bury.png"); }

.vote-num {
    display: block;
    margin-top: 36px;
    font-size: 14px;
    color: #fff;
    text-shadow: 0 1px 1px rgba(0,0,0,0.3);
}

建議將 dig/bury 圖標合併為 CSS Sprite,減少 HTTP 請求。

3. JavaScript (jQuery) 互動邏輯

$(function () {
    $('#vote .vote-btn').on('click', function () {
        var $btn     = $(this);
        var $container = $btn.parent();
        var articleId = $container.data('id');
        var type     = $btn.attr('id'); // 'dig' 或 'bury'

        // 防重複點擊 (雙重保險:前端鎖定 + 後端驗證)
        if ($btn.hasClass('disabled')) return;
        $container.find('.vote-btn').addClass('disabled').css('cursor', 'not-allowed');

        $.post('/api/vote', { id: articleId, type: type }, function (resp) {
            resp = $.trim(resp);
            if (resp === 'success') {
                // 計數 +1
                var $num = $btn.find('.vote-num');
                $num.text(parseInt($num.text(), 10) + 1);

                // 永久鎖定
                $container.find('.vote-btn').off('click').addClass('disabled');

                // 踩時額外引導留言
                if (type === 'bury') {
                    alert('感謝您的反饋,歡迎在評論區留言具體建議!');
                }
            } else if (resp === 'done') {
                alert('您已經投過票了,無法重複投票。');
                $container.find('.vote-btn').off('click').addClass('disabled');
            } else {
                alert('投票失敗,請稍後再試。');
                // 解除鎖定,允許重試
                $container.find('.vote-btn').removeClass('disabled').css('cursor', 'pointer');
            }
        }).fail(function () {
            alert('網路錯誤,請檢查連線後重試。');
            $container.find('.vote-btn').removeClass('disabled').css('cursor', 'pointer');
        });
    });
});

4. 後端 API 規範 (供參考實作)

情況HTTP 狀態回傳內容說明
投票成功200success前端計數 +1,永久鎖定
已投票200done前端提示並鎖定
參數錯誤/未登入400/401error 或 JSON 錯誤物件前端解除鎖定允許重試
伺服器錯誤500error前端解除鎖定允許重試

後端核心邏輯偽代碼

<?php
// API 端點:/api/vote
session_start();
$articleId = (int)($_POST['id'] ?? 0);
$type      = in_array($_POST['type'] ?? '', ['dig', 'bury']) ? $_POST['type'] : '';

if (!$articleId || !$type) { http_response_code(400); exit('error'); }

// 識別用戶:登入用戶用 user_id,未登入用 IP + User-Agent 雜湊
$voterKey = $_SESSION['user_id'] ?? 'anon_' . hash('sha256', $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']);

// 檢查是否已投票 (Redis Set 或資料庫唯一索引)
$redisKey = "vote:{$articleId}:{$type}";
if ($redis->sIsMember($redisKey, $voterKey)) {
    exit('done');
}

// 寫入投票
$redis->multi()
    ->sAdd($redisKey, $voterKey)
    ->hIncrBy("vote:counts:{$articleId}", $type, 1)
    ->exec();

exit('success');

進階擴充建議

  • 動畫效果:計數變更時加入 CSS transform: scale(1.2) 彈跳動畫。
  • 顯示比例:同時顯示「頂 85% / 踩 15%」進度條。
  • 取消投票:允許用戶在 5 分鐘內點擊同一按鈕取消 (需後端支援刪除)。
  • 無障礙:加入 aria-pressed、role="button"、鍵盤可聚焦操作。
  • SSR/SEO:首屏直接渲染計數,JS 僅負責互動增強。

此前端代碼結構清晰、邏輯完整,配合簡單的後端 API 即可上線,適合快速整合至任何 PHP 專案 (Laravel、ThinkPHP、CodeIgniter、原生)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved