织梦导航下拉菜单如何实现?

99ANYc3cd6
预计阅读时长 28 分钟
位置: 首页 织梦建站 正文

下面我将为你提供一种最常用、最稳定且兼容性最好的实现方法,分为详细步骤代码示例两部分,这种方法的核心是利用织梦的 channelartlist 标签来获取一级栏目,再在其循环内部嵌套 type 标签来获取当前一级栏目下的二级栏目。

织梦导航下拉菜单实现
(图片来源网络,侵删)

使用 channelartlist + type 标签(推荐)

这种方法结构清晰,易于理解和维护,是织梦官方社区推荐的实现方式。

第一步:准备HTML结构

我们需要在模板文件中(通常是 head.htmtemplets/default/header.htm)构建导航栏的HTML骨架,这个骨架清晰地表达了“一级栏目”和“二级栏目”的层级关系。

<!-- 导航栏开始 -->
<div class="nav">
    <ul class="main-nav">
        {dede:channelartlist typeid='top' row='8'}
        <li class="main-item">
            <!-- 一级栏目链接 -->
            <a href="{dede:field name='typeurl'/}" class="main-link">
                {dede:field name='typename'/}
            </a>
            <!-- 判断是否有子栏目,如果有则显示下拉框 -->
            {dede:field name='ispart' runphp='yes'}
                if(@me == 0) {
                    @me = '<div class="sub-nav"><ul class="sub-list">';
                    // 嵌套type标签获取二级栏目
                    {dede:type}
                        @me .= '<li><a href="[field:typelink/]">[field:typename/]</a></li>';
                    {/dede:type}
                    @me .= '</ul></div>';
                } else {
                    @me = '';
                }
            {/dede:field}
        </li>
        {/dede:channelartlist}
        <!-- 可以在这里添加一个首页链接 -->
        <li class="main-item"><a href="{dede:global.cfg_basehost/}" class="main-link">首页</a></li>
    </ul>
</div>
<!-- 导航栏结束 -->

代码解释:

  1. {dede:channelartlist typeid='top' row='8'}:

    织梦导航下拉菜单实现
    (图片来源网络,侵删)
    • typeid='top': 只调用顶级栏目。
    • row='8': 限制显示8个一级栏目,你可以根据需要修改。
    • 这个标签会循环每一个顶级栏目。
  2. <li class="main-item">: 这是每个一级栏目项的容器。

  3. <a href="{dede:field name='typeurl'/}" ...>: 这是当前一级栏目的链接。

  4. {dede:field name='typename'/}: 这是当前一级栏目的名称。

  5. 下拉菜单核心部分:

    织梦导航下拉菜单实现
    (图片来源网络,侵删)
    • {dede:field name='ispart' runphp='yes'}: 这是实现下拉菜单的关键。
    • ispart 字段判断当前栏目是否为“外部链接”。ispart == 0,说明它是一个普通栏目,可能包含子栏目;ispart == 1,说明它是一个外部链接,不应该显示下拉菜单。
    • runphp='yes' 允许我们在标签内使用PHP代码。
    • if(@me == 0) { ... } else { ... }: 判断逻辑,如果不是外部链接,就生成下拉菜单的HTML代码;否则,生成空字符串。
    • {dede:type} ... {/dede:type}: 在 channelartlist 循环内部,这个标签会获取当前循环项(即当前一级栏目)下的所有子栏目(二级栏目)。
    • [field:typelink/][field:typename/]: 分别是二级栏目的链接和名称。

第二步:编写CSS样式

我们需要用CSS来美化这个导航栏,并实现鼠标悬停时下拉菜单显示的效果,将以下CSS代码添加到你的模板样式文件中(通常是 style/dedecms.csstemplets/default/style.css)。

/* 导航栏基础样式 */
.nav {
    background-color: #333; /* 导航栏背景色 */
    height: 50px;          /* 导航栏高度 */
    font-family: "Microsoft YaHei", sans-serif;
}
.main-nav {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex; /* 使用Flexbox布局,让导航项水平排列 */
    align-items: center;
    height: 100%;
}
.main-item {
    position: relative; /* 关键:为下拉菜单定位提供参考 */
    margin-right: 20px;
}
.main-link {
    color: #fff;
    text-decoration: none;
    display: block;
    padding: 0 15px;
    line-height: 50px; /* 行高等于高度,使文字垂直居中 */
    font-size: 16px;
}
.main-link:hover {
    background-color: #555; /* 鼠标悬停时的背景色 */
}
/* 下拉菜单样式 */
.sub-nav {
    /* 默认隐藏下拉菜单 */
    display: none;
    /* 绝对定位,相对于其父元素 .main-item */
    position: absolute;
    top: 100%;           /* 定位在一级栏目的正下方 */
    left: 0;
    background-color: #444;
    min-width: 160px;     /* 下拉菜单的宽度 */
    box-shadow: 0 8px 16px rgba(0,0,0,0.2);
    z-index: 1000;       /* 确保下拉菜单显示在内容之上 */
}
.sub-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.sub-list li {
    width: 100%;
}
.sub-list li a {
    color: #fff;
    text-decoration: none;
    display: block;
    padding: 12px 15px;
    font-size: 14px;
}
.sub-list li a:hover {
    background-color: #555;
}
/* 鼠标悬停在一级栏目上时,显示下拉菜单 */
.main-item:hover .sub-nav {
    display: block;
}

CSS解释:

  • .main-item { position: relative; }: 这是最关键的一步,它将 .main-item 设置为定位上下文,这样里面的 .sub-nav 就可以使用 position: absolute; 相对于它进行定位。
  • .sub-nav { display: none; }: 默认状态下,下拉菜单是隐藏的。
  • .main-item:hover .sub-nav { display: block; }: 这是CSS的“后代选择器”,它的意思是:当鼠标悬停在 .main-item 上时,找到它的后代元素 .sub-nav 并将其 display 属性设置为 block,从而显示出来,这就是纯CSS实现下拉效果的核心。

第三步:可选的JavaScript增强(用于移动端或更复杂的交互)

虽然上面的CSS已经可以实现基本的下拉效果,但有时我们可能需要用JavaScript来处理更复杂的情况,

  • 在移动端,点击一级栏目展开/收起下拉菜单。
  • 解决鼠标快速移动时下拉菜单闪烁的问题。

如果不需要,可以跳过此步。

// 将此代码放在页面底部的 <script> 标签内,或引入外部JS文件
document.addEventListener('DOMContentLoaded', function() {
    const mainItems = document.querySelectorAll('.main-item');
    mainItems.forEach(item => {
        const link = item.querySelector('.main-link');
        const subNav = item.querySelector('.sub-nav');
        // 如果没有下拉菜单,则不执行任何操作
        if (!subNav) return;
        // 鼠标悬停事件(可选,可以用来优化PC端体验)
        // item.addEventListener('mouseenter', () => {
        //     subNav.style.display = 'block';
        // });
        // item.addEventListener('mouseleave', () => {
        //     subNav.style.display = 'none';
        // });
        // 点击事件(主要用于移动端)
        link.addEventListener('click', function(e) {
            // 如果是PC端且没有子菜单,则正常跳转
            if (window.innerWidth > 768 && !subNav) {
                return;
            }
            // 阻止默认跳转行为
            e.preventDefault();
            // 切换下拉菜单的显示状态
            if (subNav.style.display === 'block') {
                subNav.style.display = 'none';
            } else {
                // 先关闭其他所有打开的下拉菜单
                document.querySelectorAll('.sub-nav').forEach(nav => {
                    nav.style.display = 'none';
                });
                // 再打开当前的下拉菜单
                subNav.style.display = 'block';
            }
        });
    });
});

使用 arclist 标签(备选方案)

如果你的网站结构比较特殊,或者不想用 channelartlist,也可以用 arclist 来实现,这种方法稍微复杂一点,需要手动处理循环。

<div class="nav">
    <ul class="main-nav">
        <!-- 先循环顶级栏目 -->
        {dede:channel type='top' row='8'}
        <li class="main-item">
            <a href="[field:typeurl/]" class="main-link">[field:typename/]</a>
            <!-- 在循环内部,用arclist获取当前栏目的子栏目 -->
            {dede:arclist typeid='[field:id]' row='100'}
                <!-- arclist只输出一个循环项,我们用它来构建下拉菜单 -->
                <div class="sub-nav">
                    <ul class="sub-list">
                        <!-- 再次调用channel标签来获取所有子栏目 -->
                        {dede:channel typeid='[field:id]'}
                        <li><a href="[field:typeurl/]">[field:typename/]</a></li>
                        {/dede:channel}
                    </ul>
                </div>
            {/dede:arclist}
        </li>
        {/dede:channel}
    </ul>
</div>

注意:这种方法嵌套了三层标签,效率上可能略低于 channelartlist,且逻辑稍显绕。强烈推荐使用第一种方法


步骤 核心操作 关键代码/标签
HTML结构 搭建导航栏骨架,使用channelartlist循环一级栏目,内部用type循环二级栏目。 {dede:channelartlist}
{dede:field name='ispart' runphp='yes'}
{dede:type}
CSS样式 美化外观,实现鼠标悬停时下拉菜单的显示效果。 .main-item { position: relative; }
.sub-nav { display: none; }
.main-item:hover .sub-nav { display: block; }
JavaScript (可选) 增强交互,如处理移动端点击事件。 addEventListener('click', ...)

按照以上步骤操作,你就可以在织梦CMS中成功实现一个功能完善、外观漂亮的导航下拉菜单了,如果在实际操作中遇到问题,请检查你的栏目设置(特别是是否为外部链接)以及CSS和JS文件是否正确引入。

-- 展开阅读全文 --
头像
dede如何调用视频播放器?
« 上一篇 今天
织梦模板修改账号密码
下一篇 » 今天

相关文章

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

目录[+]