dede二三级导航如何正确调用?

99ANYc3cd6
预计阅读时长 32 分钟
位置: 首页 DEDE建站 正文
  1. 纯CSS下拉菜单(推荐) - 代码简洁,性能好,适合大多数情况。
  2. 基于jQuery的滑动/点击菜单 - 更灵活,可以实现更丰富的动画效果。

准备工作:模板文件结构

无论使用哪种方法,你都需要在模板文件中准备好HTML结构,通常是在网站的头部模板文件 head.htmheader.htm 中进行操作。

dede二三级导航调用
(图片来源网络,侵删)

假设你的栏目结构如下:

  • 一级栏目 A
    • 二级栏目 A1
    • 二级栏目 A2
      • 三级栏目 A2-1
      • 三级栏目 A2-2
  • 一级栏目 B

    二级栏目 B1

  • 一级栏目 C

纯CSS下拉菜单

这种方法的核心是利用CSS的 hover 伪类来控制子菜单的显示和隐藏。

第1步:修改模板文件,添加HTML结构

head.htm 中,找到你的导航区域,将默认的导航标签替换为以下结构:

dede二三级导航调用
(图片来源网络,侵删)
<!-- 顶部导航开始 -->
<div class="nav">
    <ul id="topnav">
        {dede:channel type='top' row='8'}
        <li>
            <a href="[field:typelink/]">[field:typename/]</a>
            <!-- 检查是否有子栏目 -->
            [field:sonlist]
            <ul class="subnav">
                <!-- 循环输出二级栏目 -->
                {dede:son typeid='[field:id]'}
                <li>
                    <a href="[field:typelink/]">[field:typename/]</a>
                    <!-- 检查二级栏目下是否有三级栏目 -->
                    [field:sonlist]
                    <ul class="sub-subnav">
                        {dede:son typeid='[field:id]'}
                        <li><a href="[field:typelink/]">[field:typename/]</a></li>
                        {/dede:son}
                    </ul>
                    {/field:sonlist}
                </li>
                {/dede:son}
            </ul>
            {/field:sonlist}
        </li>
        {/dede:channel}
        <!-- 可以添加一个“首页”链接 -->
        <li><a href='{dede:global.cfg_cmsurl/}/' class='nav-home'>首页</a></li>
    </ul>
</div>
<!-- 顶部导航结束 -->

代码解析:

  • {dede:channel type='top' row='8'}: 调用顶级栏目(一级栏目)。
  • [field:sonlist]: 这是一个自定义字段,但默认是不存在的。我们需要手动在DedeCMS的后台为其添加功能。
    • 如何添加 [field:sonlist] 功能:
      1. 打开 /include/taglib/channel.lib.php 文件。
      2. 找到大约第92行左右的 $linktype = "<a href='".$typeinfos['typedir']."'>"; 这一行。
      3. 在这一行前面,添加如下代码:
        // 判断是否有子栏目
        $sonids = GetSonIds($typeid, 0, false);
        if($sonids != ''){
            $GLOBALS['autoindex'] = 0;
            $sonlist = '';
            $dsql->SetQuery("SELECT id,typename,typedir,isdefault,defaultname,ishidden,moresite,siteurl,sitepath FROM `dede_arctype` WHERE reid='$typeid' And ishidden<>1 order by sortrank asc");
            $dsql->Execute('al');
            while($row = $dsql->GetArray('al'))
            {
                $sonlist .= "<a href='".$row['typedir']."'>".$row['typename']."</a>\r\n";
            }
            $fields['sonlist'] = $sonlist;
        }else{
            $fields['sonlist'] = '';
        }
      4. 保存文件,这样 [field:sonlist] 就会输出当前栏目下的所有二级栏目的链接。注意:上面的代码会直接输出链接,为了我们上面的HTML结构,需要做微调。
      5. 更简单的方法(推荐): 直接使用 {dede:son} 标签嵌套,如上面的完整HTML代码所示,它更清晰,更符合逻辑,我们不需要修改 channel.lib.php,直接使用 {dede:son} 即可。

第2步:添加CSS样式

在模板的CSS文件(如 style.css)中添加以下样式:

/* 导航容器样式 */
.nav {
    width: 100%;
    background-color: #333; /* 导航背景色 */
    height: 40px;
    line-height: 40px;
}
#topnav, #topnav ul {
    list-style: none;
    padding: 0;
    margin: 0;
    float: left; /* 导航居中布局需要调整 */
}
#topnav > li {
    float: left;
    position: relative;
    margin-right: 1px;
}
#topnav > li > a {
    display: block;
    padding: 0 15px;
    color: #fff;
    text-decoration: none;
}
/* 鼠标悬停时,一级菜单背景变化 */
#topnav > li:hover > a {
    background-color: #555;
}
/* 二级菜单样式 */
#topnav li ul.subnav {
    position: absolute;
    top: 40px; /* 与一级菜单高度相同 */
    left: 0;
    width: 180px;
    background-color: #444;
    display: none; /* 默认隐藏 */
    z-index: 999;
}
/* 鼠标悬停在一级菜单上时,显示二级菜单 */
#topnav li:hover > ul.subnav {
    display: block;
}
/* 三级菜单样式 */
#topnav li ul.subnav li {
    position: relative;
    width: 100%;
}
#topnav li ul.subnav li a {
    display: block;
    padding: 8px 15px;
    color: #ccc;
    border-bottom: 1px solid #555;
}
/* 鼠标悬停在二级菜单上时,显示三级菜单 */
#topnav li ul.subnav li:hover > ul.sub-subnav {
    display: block;
}
#topnav li ul.subnav li ul.sub-subnav {
    position: absolute;
    top: 0;
    left: 180px; /* 与二级菜单宽度相同 */
    background-color: #444;
    display: none; /* 默认隐藏 */
}
#topnav li ul.subnav li ul.sub-subnav li a {
    border-bottom: none;
}

CSS解析:

  • position: absolute;: 将子菜单从正常的文档流中脱离,并相对于其最近的已定位祖先元素(这里是<li>)进行定位。
  • top: 40px; left: 0;: 控制二级菜单相对于一级菜单的位置。
  • display: none;: 默认隐藏子菜单。
  • #topnav li:hover > ul.subnav { display: block; }: 这是核心的CSS选择器,当鼠标悬停在<li>元素上时,选择其直接子元素ul.subnav并将其display属性设置为block,从而实现显示。

基于jQuery的滑动/点击菜单

这种方法使用JavaScript来控制菜单的显示,可以实现更平滑的动画效果,并且可以解决iOS等设备上hover不生效的问题。

dede二三级导航调用
(图片来源网络,侵删)

第1步:修改模板文件,添加HTML结构

HTML结构可以和方法一完全一样,也可以简化一些,因为jQuery可以更灵活地处理。

<!-- 顶部导航开始 -->
<div class="nav">
    <ul id="topnav">
        {dede:channel type='top' row='8'}
        <li class="menu-item">
            <a href="[field:typelink/]">[field:typename/]</a>
            <!-- 用一个容器来包裹子菜单 -->
            <div class="sub-menu-container">
                {dede:son typeid='[field:id]'}
                <div class="sub-menu-item">
                    <a href="[field:typelink/]">[field:typename/]</a>
                    {dede:son typeid='[field:id]'}
                    <div class="sub-sub-menu">
                        <a href="[field:typelink/]">[field:typename/]</a>
                    </div>
                    {/dede:son}
                </div>
                {/dede:son}
            </div>
        </li>
        {/dede:channel}
        <li><a href='{dede:global.cfg_cmsurl/}/' class='nav-home'>首页</a></li>
    </ul>
</div>
<!-- 顶部导航结束 -->

注意: 这里我调整了HTML结构,用 div 包裹子菜单,方便jQuery选择器操作,你可以根据自己的喜好调整。

第2步:引入jQuery库

在模板文件的<head>部分,确保引入了jQuery库,通常放在{dede:include filename='head.htm'/}之前。

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

第3步:添加CSS样式

CSS可以简化,不需要hover伪类。

/* 导航容器样式(同上) */
.nav { width: 100%; background-color: #333; height: 40px; line-height: 40px; }
#topnav, #topnav ul { list-style: none; padding: 0; margin: 0; float: left; }
#topnav > li { float: left; position: relative; margin-right: 1px; }
#topnav > li > a { display: block; padding: 0 15px; color: #fff; text-decoration: none; }
/* 子菜单容器 */
.sub-menu-container {
    position: absolute;
    top: 100%;
    left: 0;
    background-color: #444;
    min-width: 180px;
    display: none; /* 默认隐藏 */
    z-index: 999;
}
/* 三级菜单 */
.sub-sub-menu {
    position: absolute;
    top: 0;
    left: 100%;
    background-color: #444;
    display: none; /* 默认隐藏 */
}
.sub-menu-item {
    position: relative;
}

第4步:添加jQuery脚本

在模板文件的底部,</body>标签之前,添加以下jQuery代码:

<script>
$(document).ready(function(){
    // 鼠标悬停显示子菜单
    $('.menu-item').hover(
        function() { // 鼠标进入
            $(this).find('.sub-menu-container').stop(true, true).slideDown(200); // 使用slideDown实现滑动效果
        },
        function() { // 鼠标离开
            $(this).find('.sub-menu-container').stop(true, true).slideUp(200);
        }
    );
    // 如果需要三级菜单,可以再嵌套一个hover事件
    $('.sub-menu-item').hover(
        function() {
            $(this).find('.sub-sub-menu').stop(true, true).slideDown(200);
        },
        function() {
            $(this).find('.sub-sub-menu').stop(true, true).slideUp(200);
        }
    );
});
</script>

jQuery解析:

  • $(document).ready(function(){...});: 确保DOM加载完成后再执行脚本。
  • $('.menu-item').hover(...): 为所有带有.menu-item类的元素绑定鼠标悬停事件。
  • function() { ... }: 鼠标进入时执行的函数,使用.slideDown(200)让子菜单在200毫秒内滑动显示。
  • function() { ... }: 鼠标离开时执行的函数,使用.slideUp(200)让子菜单在200毫秒内滑动隐藏。
  • stop(true, true): 这个方法可以停止正在进行的动画,防止鼠标快速移动时动画卡顿。

总结与建议

特性 方法一 (纯CSS) 方法二 (jQuery)
性能 ,无JavaScript开销 稍低,需要加载jQuery库并执行JS
兼容性 现代浏览器支持良好,iOS设备hover有兼容问题 非常好,所有浏览器和设备都支持
实现难度 简单,只需HTML和CSS 稍复杂,需要HTML、CSS和JS
动画效果 只能显示/隐藏,无法做平滑动画 可以轻松实现滑动、淡入淡出等动画
代码量 CSS可能较长 HTML和CSS相对简洁,JS代码量小

我的建议:

  • 对于大多数追求性能和简洁的网站,方法一(纯CSS)是首选,它足够强大,且不依赖任何外部库。
  • 如果你的网站需要动画效果,或者希望在移动设备上有更好的交互体验,或者你的网站本身就已经大量使用了jQuery,那么方法二(jQuery)是更好的选择。

在实际操作中,请根据你网站的实际情况和栏目结构,对提供的代码进行微调。

-- 展开阅读全文 --
头像
dede会员中心模版如何修改或自定义?
« 上一篇 前天
如何调用?
下一篇 » 前天

相关文章

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

目录[+]