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

PHP + JavaScript 實現下拉導航菜單:CSS/JS 純前端交互完整代碼

     編輯:PHP 綜合知識

經典下拉導航菜單:CSS 佈局 + JS 狀態機 + 延遲隱藏體驗優化

下拉菜單是網站導航核心組件。本文提供一個零依賴、純 CSS+JS 實現:語義化 HTML 結構、CSS 絕對定位隱藏/顯示、JavaScript 管理鼠標進出延遲計時器,防止誤觸發抖動,兼容性極佳。

完整代碼(HTML + CSS + JS)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
/* === 基礎樣式 === */
#sddm { margin: 0; padding: 0; list-style: none; font-family: arial; }
#sddm li { float: left; position: relative; }
#sddm li a { display: block; padding: 8px 15px; color: #2875DE; text-decoration: none; background: #EAEBD8; }
#sddm li a:hover { background: #49A3FF; color: #FFF; }

/* === 子菜單面板 === */
#sddm div {
    position: absolute;
    visibility: hidden;
    top: 100%; left: 0;
    margin: 0; padding: 0;
    background: #EAEBD8;
    border: 1px solid #5970B2;
    min-width: 160px;
    z-index: 100;
}
#sddm div a {
    position: relative;
    display: block;
    padding: 5px 10px;
    white-space: nowrap;
    color: #2875DE;
    background: #EAEBD8;
}
#sddm div a:hover { background: #49A3FF; color: #FFF; }
</style>
</head>
<body>

<ul id="sddm">
    <li><a href="/">首頁</a></li>

    <li>
        <a href="/about" onmouseover="mopen('m1')" onmouseout="mclosetime()">關於我們</a>
        <div id="m1" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
            <a href="#">公司簡介</a>
            <a href="#">企業文化</a>
            <a href="#">榮譽資質</a>
            <a href="#">發展歷程</a>
        </div>
    </li>

    <li>
        <a href="/news" onmouseover="mopen('m2')" onmouseout="mclosetime()">新聞中心</a>
        <div id="m2" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
            <a href="#">公司新聞</a>
            <a href="#">行業動態</a>
            <a href="#">媒體報道</a>
        </div>
    </li>

    <li>
        <a href="/solution" onmouseover="mopen('m3')" onmouseout="mclosetime()">解決方案</a>
        <div id="m3" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
            <a href="#">行業方案</a>
            <a href="#">技術架構</a>
            <a href="#">案例研究</a>
        </div>
    </li>

    <li>
        <a href="/product" onmouseover="mopen('m4')" onmouseout="mclosetime()">產品展示</a>
        <div id="m4" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
            <a href="#">硬體產品</a>
            <a href="#">軟體服務</a>
            <a href="#">增值服務</a>
        </div>
    </li>

    <li>
        <a href="/support" onmouseover="mopen('m5')" onmouseout="mclosetime()">支持與下載</a>
        <div id="m5" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
            <a href="#">驅動下載</a>
            <a href="#">使用手冊</a>
            <a href="#">常見問題</a>
            <a href="#">工單提交</a>
        </div>
    </li>

    <li>
        <a href="/jobs" onmouseover="mopen('m6')" onmouseout="mclosetime()">人才招聘</a>
        <div id="m6" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
            <a href="#">社招崗位</a>
            <a href="#">校招專區</a>
            <a href="#">實習生計劃</a>
        </div>
    </li>

    <li>
        <a href="/contact" onmouseover="mopen('m7')" onmouseout="mclosetime()">聯系我們</a>
        <div id="m7" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
            <a href="#">聯系方式</a>
            <a href="#">在線留言</a>
            <a href="#">地圖導航</a>
        </div>
    </li>
</ul>

<script>
// === 狀態管理 ===
var timeout = 500;      // 延遲隱藏毫秒數
var closetimer = 0;     // 計時器 ID
var ddmenuitem = 0;     // 當前顯示的子菜單元素

// 顯示指定子菜單
function mopen(id) {
    mcancelclosetime();                 // 取消待執行的隱藏
    if (ddmenuitem) ddmenuitem.style.visibility = 'hidden'; // 隱藏舊菜單
    ddmenuitem = document.getElementById(id);
    ddmenuitem.style.visibility = 'visible';
}

// 隱藏當前子菜單
function mclose() {
    if (ddmenuitem) ddmenuitem.style.visibility = 'hidden';
}

// 啟動隱藏計時器
function mclosetime() {
    closetimer = window.setTimeout(mclose, timeout);
}

// 取消隱藏計時器
function mcancelclosetime() {
    if (closetimer) {
        window.clearTimeout(closetimer);
        closetimer = null;
    }
}

// 點擊頁面其他區域關閉菜單
document.onclick = mclose;
</script>
</body>
</html>

核心交互邏輯:延遲隱藏狀態機

事件觸發元素處理函數作用
mouseover主菜單 <a>mopen(id)取消隱藏計時、隱藏舊菜單、顯示目標菜單
mouseout主菜單 <a>mclosetime()啟動 500ms 計時器,延後隱藏
mouseover子菜單 <div>mcancelclosetime()鼠標移入子菜單區域,取消隱藏計時
mouseout子菜單 <div>mclosetime()鼠標移出子菜單,重新啟動計時
clickdocumentmclose()點擊空白處強制關閉

這套「進入即顯、離開延遲、子區域保護」邏輯,解決了菜單項間縫隙導致的閃爍、誤關閉等經典體驗問題。

現代化改造建議

  1. CSS :hover 純樣式版:簡單二級菜單可完全用 li:hover > div { visibility: visible; } 實現,無 JS 依賴,但無法控制延遲與點擊外部關閉。
  2. ARIA 無障礙增強:添加 role="menubar"、aria-haspopup="true"、aria-expanded、鍵盤 Tab/Enter/Esc 支持。
  3. 響應式斷點:移動端改為漢堡菜單 + 側滑抽屉,CSS @media (max-width: 768px) 切換佈局。
  4. 框架組件化:Vue/React 可封裝為 <DropdownMenu :items="menuData" />,狀態內建、可複用、可測試。

PHP 動態生成菜單數據

<?php
// 假設從數據庫讀取菜單結構
$menu = [
    ['name' => '關於我們', 'url' => '/about', 'children' => [
        ['name' => '公司簡介', 'url' => '/about/profile'],
        ['name' => '企業文化', 'url' => '/about/culture'],
    ]],
    ['name' => '新聞中心', 'url' => '/news', 'children' => [
        ['name' => '公司新聞', 'url' => '/news/company'],
        ['name' => '行業動態', 'url' => '/news/industry'],
    ]],
    // ...
];

function renderMenu($items, $level = 0) {
    $idPrefix = $level === 0 ? 'm' : 'sub';
    static $counter = 0;
    echo $level === 0 ? '<ul id="sddm">' : '<ul class="sub-menu">';
    foreach ($items as $item) {
        $counter++;
        $menuId = $idPrefix . $counter;
        $hasChildren = !empty($item['children']);
        echo '<li>';
        $attrs = $hasChildren ? "onmouseover=\"mopen('$menuId')\" onmouseout=\"mclosetime()\"" : '';
        echo "<a href=\"{$item['url']}\" $attrs>{$item['name']}</a>";
        if ($hasChildren) {
            echo "<div id=\"$menuId\" onmouseover=\"mcancelclosetime()\" onmouseout=\"mclosetime()\">";
            renderMenu($item['children'], $level + 1);
            echo '</div>';
        }
        echo '</li>';
    }
    echo '</ul>';
}

renderMenu($menu);
?>

從靜態代碼到動態渲染,從桌面端到響應式,下拉菜單的演進映照著前端工程化的歷程。掌握原生實現原理,才能在選型組件庫時心中有數、不被綁架。

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