dede5.7二级导航如何实现?

99ANYc3cd6
预计阅读时长 32 分钟
位置: 首页 DEDE建站 正文
  1. 推荐使用 CSS 下拉菜单(纯静态,最稳定)
  2. 使用 JavaScript 动态加载(适合内容频繁更新的栏目)

准备工作:修改顶部模板文件

无论使用哪种方法,首先都需要修改您的网站头部模板,通常是 /templets/default/header.htm 文件。

dede5.7二级导航
(图片来源网络,侵删)
  1. 登录DedeCMS后台:进入“模板” -> “默认模板管理”。
  2. 找到并编辑 header.htm:点击“修改”按钮。
  3. 定位导航代码:找到类似 {dede:channel type='top' row='8'} 的标签,这就是您的一级导航代码。

CSS 下拉菜单(推荐)

这种方法利用 CSS 的 hover 伪类,当鼠标移动到一级菜单上时,自动显示对应的二级菜单,它不需要额外的 JS 文件,加载速度快,兼容性好。

第1步:修改 header.htm 文件

{dede:channel} 标签中,我们需要为每个一级菜单项增加一个 class,并让它能调用出它的子栏目,修改后的代码如下:

<div id="nav">
    <ul>
        {dede:channel type='top' row='8'}
        <li>
            <!-- 
             * a 标签是显示一级菜单名称
             * class="mainlevel" 用于CSS样式
             * [field:typelink/] 是栏目链接
            -->
            <a href="[field:typelink/]" class="mainlevel">[field:typename/]</a>
            <!-- 
             * div id="sub_[field:id/]" 是存放二级菜单的容器
             * style="display:none;" 默认隐藏
             * class="subnav" 用于CSS样式
            -->
            <div id="sub_[field:id/]" class="subnav" style="display:none;">
                <!-- 
                 * 在这里调用当前一级栏目下的所有子栏目
                 *typeid='[field:id/]' 指定当前父栏目ID
                 *row='10' 最多显示10个子栏目
                -->
                {dede:channel type='son' typeid='[field:id/]' row='10'}
                <a href="[field:typelink/]">[field:typename/]</a>
                {/dede:channel}
            </div>
        </li>
        {/dede:channel}
        <!-- 可以加上一个首页链接 -->
        <li><a href="{dede:global.cfg_basehost/}" class="mainlevel">首页</a></li>
    </ul>
</div>

代码解释

  • {dede:channel type='top'}:循环输出顶级栏目。
  • <a class="mainlevel">...</a>:一级菜单链接,我们给它一个 mainlevel 类以便添加样式。
  • <div id="sub_[field:id/]" class="subnav" style="display:none;">:这是二级菜单的容器。id 是唯一的(sub_1, sub_2...),class 用于统一样式,style="display:none;" 用于初始隐藏。
  • {dede:channel type='son' typeid='[field:id/]'}:这是关键!它嵌套在一级菜单的 li 标签内,用于输出当前顶级栏目下的所有子栏目。typeid 的值通过 [field:id/] 动态获取。

第2步:添加 CSS 样式

将以下 CSS 代码添加到您的模板 CSS 文件中(通常是 /templets/default/style/dedecms.css),或者在 header.htm<head> 部分使用 <style> 标签嵌入。

dede5.7二级导航
(图片来源网络,侵删)
/* 导航容器样式 */
#nav {
    height: 40px;
    background-color: #333; /* 导航栏背景色 */
    font-size: 14px;
}
#nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
}
#nav li {
    float: left; /* 让菜单项横向排列 */
    position: relative; /* 关键:为下拉菜单定位提供参考 */
}
#nav .mainlevel {
    display: block;
    padding: 0 15px;
    line-height: 40px;
    color: #fff;
    text-decoration: none;
}
#nav .mainlevel:hover {
    background-color: #555; /* 鼠标悬停时一级菜单的背景色 */
}
/* 二级菜单容器样式 */
#nav .subnav {
    position: absolute; /* 关键:脱离文档流,进行绝对定位 */
    top: 40px; /* 定位在一级菜单的下方 */
    left: 0;
    width: 200px; /* 设置二级菜单的宽度 */
    background-color: #444; /* 二级菜单背景色 */
    border: 1px solid #666;
    z-index: 999; /* 确保菜单显示在最上层 */
}
/* 鼠标悬停在一级菜单上时,显示二级菜单 */
#nav li:hover .subnav {
    display: block;
}
/* 二级菜单链接样式 */
#nav .subnav a {
    display: block;
    padding: 10px 15px;
    color: #fff;
    text-decoration: none;
    border-bottom: 1px solid #555;
}
#nav .subnav a:hover {
    background-color: #555; /* 鼠标悬停在二级菜单项上时的背景色 */
}

CSS 核心逻辑

  • #nav li { position: relative; }:让每个一级菜单 li 成为二级菜单 div 的定位基准。
  • #nav .subnav { position: absolute; top: 40px; }:让二级菜单相对于它的父级 li 进行绝对定位,并出现在其下方。
  • #nav li:hover .subnav { display: block; }:这是实现下拉的核心,当鼠标悬停在 li 上时,其内部的 .subnav 元素(二级菜单)的 display 属性从 none 变为 block,从而显示出来。

JavaScript 动态加载

如果你的二级栏目内容非常多,或者需要频繁更新,使用 CSS 可能会导致页面体积较大,这时可以用 JS 来动态加载二级菜单,实现“按需加载”,提高页面首屏加载速度。

第1步:修改 header.htm 文件

这里的结构比 CSS 方法更简单,二级菜单的容器初始是空的。

<div id="nav">
    <ul>
        {dede:channel type='top' row='8'}
        <li>
            <a href="[field:typelink/]" class="mainlevel nav-link" data-id="[field:id/]">[field:typename/]</a>
            <!-- 二级菜单容器,初始为空 -->
            <div class="subnav" id="subnav_[field:id/]" style="display:none;"></div>
        </li>
        {/dede:channel}
        <li><a href="{dede:global.cfg_basehost/}" class="mainlevel">首页</a></li>
    </ul>
</div>

关键改动

dede5.7二级导航
(图片来源网络,侵删)
  • 一级链接 <a> 增加了 class="nav-link"data-id="[field:id/]" 属性。data-id 用于 JS 识别需要加载哪个栏目的子内容。
  • 二级菜单 <div> 的内容是空的,只保留了容器和 id

第2步:创建 JS 文件并调用

  1. 在您的模板目录下创建一个 JS 文件,/templets/default/js/nav.js
  2. 将以下代码复制到 nav.js 文件中:
document.addEventListener('DOMContentLoaded', function() {
    // 获取所有带有 nav-link 类的一级菜单链接
    const navLinks = document.querySelectorAll('.nav-link');
    navLinks.forEach(link => {
        link.addEventListener('mouseenter', function() {
            const parentId = this.getAttribute('data-id'); // 获取 data-id 的值
            const subNavContainer = document.getElementById('subnav_' + parentId); // 找到对应的二级菜单容器
            // 如果容器还没有内容,则通过AJAX加载
            if (subNavContainer && subNavContainer.innerHTML === '') {
                // 这里使用DedeCMS的arclist标签来模拟AJAX获取数据
                // 实际项目中,你可能需要一个独立的PHP接口来返回JSON数据
                // 这里为了方便,直接拼接HTML
                let subItems = '';
                // !!!重要提示:这里的URL需要根据你的网站结构调整
                // 这只是一个示例,实际中不能直接在前端模板里写死PHP逻辑
                // 更好的做法是创建一个 /include/get_subnav.php 文件,然后通过 fetch 调用
                // 这里为了简化,我们假设你有一个办法能获取到数据
                // 我们用一个假的循环来模拟
                // {dede:channel type='son' typeid='[field:id/]' row='10'}
                //     subItems += `<a href="[field:typelink/]">[field:typename/]</a>`;
                // {/dede:channel}
                // 由于JS无法直接执行Dede标签,这里我们用一个占位符,你需要用其他方式填充它
                subItems = '<a href="#">子栏目1</a><a href="#">子栏目2</a>'; // 替换为你的真实数据
                subNavContainer.innerHTML = subItems;
            }
            // 显示二级菜单
            if (subNavContainer) {
                subNavContainer.style.display = 'block';
            }
        });
        link.addEventListener('mouseleave', function() {
            const subNavContainer = document.getElementById('subnav_' + this.getAttribute('data-id'));
            if (subNavContainer) {
                // 延迟隐藏,避免鼠标从一级菜单快速移动到二级菜单时菜单消失
                setTimeout(() => {
                    subNavContainer.style.display = 'none';
                }, 300);
            }
        });
    });
});

JS 代码逻辑说明

  • 监听所有一级菜单的 mouseenter(鼠标进入)事件。
  • 当鼠标进入时,通过 data-id 找到对应的二级菜单容器。
  • 检查容器是否为空:如果为空,说明是第一次加载,此时去获取子栏目的数据并填充进去。注意:JS 无法直接执行 Dede 标签,上面代码中的 subItems 是一个占位符,在实际项目中,你需要:
    • 创建一个独立的 PHP 文件(get_subnav.php),接收 typeid 参数,并用 {dede:channel type='son'} 查询数据,然后返回 HTML 片段或 JSON。
    • 在 JS 中使用 fetch()ajax() 方法调用这个 PHP 文件,获取数据后再填充到容器中。
  • 显示填充好内容的二级菜单。
  • 监听 mouseleave(鼠标离开)事件,延迟一段时间后隐藏二级菜单,提升用户体验。

第3步:引入 JS 和 CSS

header.htm</head> 标签之前,引入你创建的 JS 文件,并添加一些基本的 CSS 样式(和方法一中的 CSS 类似,但不需要 hover 规则)。

<!-- 在 head 部分添加 -->
<link rel="stylesheet" type="text/css" href="{dede:global.cfg_templets_skin/}/style/dedecms.css" />
<style>
    /* 这里放方法二中提到的基本CSS样式,但去掉 #nav li:hover .subnav 的规则 */
    #nav { height: 40px; background-color: #333; }
    #nav ul { list-style: none; margin: 0; padding: 0; }
    #nav li { float: left; position: relative; }
    #nav .mainlevel { display: block; padding: 0 15px; line-height: 40px; color: #fff; text-decoration: none; }
    #nav .mainlevel:hover { background-color: #555; }
    #nav .subnav { position: absolute; top: 40px; left: 0; width: 200px; background-color: #444; border: 1px solid #666; z-index: 999; }
    #nav .subnav a { display: block; padding: 10px 15px; color: #fff; text-decoration: none; border-bottom: 1px solid #555; }
    #nav .subnav a:hover { background-color: #555; }
</style>
<script src="{dede:global.cfg_templets_skin/}/js/nav.js"></script>

总结与建议

特性 方法一 (CSS) 方法二 (JS)
实现难度 简单,只需修改模板和CSS 中等,需要JS和少量后端知识
加载速度 ,无额外请求,CSS文件小 首屏快,二级菜单按需加载,适合复杂导航
维护性 ,纯静态,逻辑清晰 较低,JS逻辑稍复杂,需要处理AJAX
兼容性 非常好,所有现代浏览器都支持 非常好,但需确保JS未禁用

对于 DedeCMS 5.7 这种老系统,我强烈推荐使用【方法一:CSS 下拉菜单】,它简单、稳定、高效,完全能满足大多数网站的需求,且不需要复杂的编程,只有在栏目层级非常深、二级内容极其庞大时,才考虑使用方法二来优化性能。

-- 展开阅读全文 --
头像
C语言中Ctrl+C如何退出程序?
« 上一篇 02-27
dede首页缩略图标签怎么用?
下一篇 » 02-27

相关文章

取消
微信二维码
支付宝二维码

目录[+]