如何让织梦点击出现二级栏目?

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

核心思路

无论使用哪种方法,核心逻辑都是一样的:

织梦点击出现二级栏目
(图片来源网络,侵删)
  1. 后端准备:在PHP模板中,我们需要为每个一级栏目都生成一个包含其所有二级栏目列表的HTML结构,但这个二级列表在初始状态下是隐藏的(通过CSS的 display: none; 实现)。
  2. 前端交互:当用户点击一级栏目时,通过JavaScript来触发一个事件,这个事件会做两件事:
    • 隐藏当前所有已展开的二级栏目列表(如果有的话)。
    • 显示被点击的一级栏目对应的二级栏目列表。

纯CSS + HTML (最简洁,推荐首选)

这种方法利用了HTML的 target 伪类,不需要编写任何JavaScript代码,非常简洁和优雅。

优点

  • 代码量少:无需JS,易于维护。
  • 性能好:没有额外的JavaScript解析和执行开销。
  • SEO友好:即使没有JS,链接也是有效的。

缺点

  • URL会变化:点击后,URL的末尾会加上一个锚点(如 #nav1),虽然不影响功能,但可能会让一些用户感到困惑。
  • 交互体验略有不同:无法通过点击外部区域来关闭菜单。

实现步骤

第一步:修改一级栏目循环模板

找到你网站首页或栏目页的一级栏目循环代码,通常在 head.htmindex.htm 文件中,默认代码可能长这样:

{dede:channel type='top' currentstyle="<li class='thisclass'><a href='~typelink~'>~typename~</a></li>"}
    <li><a href='[field:typelink/]'>[field:typename/]</a></li>
{/dede:channel}

你需要将其修改为下面的结构,这里我们为每个一级栏目链接添加一个 id,并创建一个隐藏的二级栏目列表容器。

织梦点击出现二级栏目
(图片来源网络,侵删)
{dede:channel type='top' currentstyle="<li class='thisclass'><a href='~typelink~' id='~id~'>~typename~</a></li>"}
    <li>
        <!-- 
            为一级栏目链接添加一个唯一的ID,'nav1', 'nav2'...
            这个ID将作为后面二级列表容器的锚点。
        -->
        <a href="[field:typelink/]" id="nav[field:id/]">[field:typename/]</a>
        <!-- 
            创建一个二级栏目列表容器。
            注意:class="sub-menu" 和 style="display: none;" 是关键。
            它的id必须和上面一级链接的id对应,并在末尾加上'-content'。
        -->
        <ul class="sub-menu" id="nav[field:id/]-content" style="display: none;">
            {dede:channel type='son' noself='yes'}
                <li><a href="[field:typelink/]">[field:typename/]</a></li>
            {dede:channel}
        </ul>
    </li>
{/dede:channel}

代码解释

  • id="nav[field:id/]":为每个一级链接设置一个唯一的ID,如 nav1, nav2[field:id] 是织梦的栏目ID字段。
  • class="sub-menu":给二级列表一个类名,方便我们用CSS来控制它的样式。
  • id="nav[field:id/]-content":为二级列表容器设置一个与一级链接ID对应的ID,如 nav1-content, nav2-content,这是target选择器能工作的关键。
  • style="display: none;":初始状态下,二级列表是隐藏的。
  • {dede:channel type='son' noself='yes'}:这是一个嵌套的循环,用于获取当前一级栏目下的所有二级栏目。type='son' 表示获取子栏目。

第二步:添加CSS样式

在你的CSS文件(通常是 /templets/你的模板/style/ 目录下的文件)中,添加以下样式:

/* 默认隐藏所有二级菜单 */
.sub-menu {
    display: none;
}
/* 当一级链接被点击后(URL变为 #nav1-content),对应的二级菜单就会显示 */
/* 当URL是 http://你的网站/#nav1-content 时,id为nav1-content的ul就会显示 */
#nav1-content:target,
#nav2-content:target,
#nav3-content:target,
#nav4-content:target {
    display: block;
}
/* (可选) 美化样式,让下拉菜单更美观 */
.sub-menu {
    list-style: none;
    padding-left: 0;
    margin-top: 10px;
    /* 可以添加背景色、边框等 */
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    border-radius: 4px;
}
.sub-menu li {
    padding: 8px 15px;
}
.sub-menu li a {
    color: #333;
    text-decoration: none;
    display: block;
}
.sub-menu li a:hover {
    background-color: #eee;
}

注意:CSS选择器 #nav1-content:target, #nav2-content:target... 需要你根据网站实际的栏目数量来写全,如果你的栏目很多,可以考虑用JavaScript来动态添加样式,但这样就失去了纯CSS的意义,对于大多数网站(栏目数<20),手动写全是完全可行的。

至此,方法一就完成了,刷新你的网站,点击一级栏目,应该就能看到对应的二级栏目了。


JavaScript + CSS (更灵活,URL不变)

如果你不希望URL因为点击而改变,或者需要更复杂的交互(如点击外部关闭菜单),那么JavaScript是更好的选择。

优点

  • URL保持不变:用户体验更好。
  • 交互灵活:可以实现更复杂的逻辑,如点击外部关闭菜单、添加动画效果等。

缺点

  • 需要编写和引入JS:比纯CSS方法多一步操作。
  • 依赖JavaScript:如果用户禁用了JS,这个功能将失效(但一级栏目的链接仍然有效)。

实现步骤

第一步:修改一级栏目循环模板

这一步和方法一的第一步基本一样,但我们可以去掉 style="display: none;",因为我们将用JS来控制显示和隐藏。

{dede:channel type='top' currentstyle="<li class='thisclass'><a href='~typelink~' data-id='~id~'>~typename~</a></li>"}
    <li>
        <!-- 
            这里我们使用 data-id 属性来存储栏目ID,这是HTML5的标准做法,比在JS中解析ID更可靠。
        -->
        <a href="[field:typelink/]" data-id="nav[field:id/]">[field:typename/]</a>
        <ul class="sub-menu" id="nav[field:id/]-content">
            {dede:channel type='son' noself='yes'}
                <li><a href="[field:typelink/]">[field:typename/]</a></li>
            {dede:channel}
        </ul>
    </li>
{/dede:channel}

代码变化

  • 我们将 id 换成了 data-id="nav[field:id/]",并将 data-id 赋给了一级链接,而不是二级列表容器,这是一种更清晰的JS交互模式。
  • 二级列表容器的 id 依然保留,但移除了内联的 display: none;

第二步:添加CSS样式

CSS只需要设置二级列表的默认隐藏状态即可。

/* 默认隐藏所有二级菜单 */
.sub-menu {
    display: none;
    /* (可选) 添加美化和过渡动画 */
    list-style: none;
    padding-left: 0;
    margin-top: 10px;
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    border-radius: 4px;
    /* 添加平滑过渡效果 */
    transition: all 0.3s ease-in-out;
}
.sub-menu li {
    padding: 8px 15px;
}
.sub-menu li a {
    color: #333;
    text-decoration: none;
    display: block;
}
.sub-menu li a:hover {
    background-color: #eee;
}

第三步:创建并引入JavaScript文件

  1. 创建JS文件:在你的模板目录下(/templets/你的模板/js/)创建一个新的文件,命名为 dropdown_menu.js

  2. 编写JS代码:将以下代码复制到 dropdown_menu.js 文件中。

document.addEventListener('DOMContentLoaded', function() {
    // 1. 获取所有的一级栏目链接
    const topLevelLinks = document.querySelectorAll('a[data-id]');
    // 2. 获取所有的二级栏目列表
    const subMenus = document.querySelectorAll('.sub-menu');
    // 为每个一级链接添加点击事件监听器
    topLevelLinks.forEach(function(link) {
        link.addEventListener('click', function(event) {
            // 阻止链接的默认跳转行为,因为我们只想触发下拉菜单
            // 注意:如果用户按住Ctrl/Cmd点击在新标签页打开,这个阻止可能不生效,这是正常行为。
            event.preventDefault();
            // 获取被点击链接的 data-id 属性值,'nav1'
            const clickedLinkId = this.getAttribute('data-id');
            // 构建对应二级列表的ID,'nav1-content'
            const targetSubMenuId = clickedLinkId + '-content';
            // 在所有二级列表中找到那个目标列表
            const targetSubMenu = document.getElementById(targetSubMenuId);
            // 先隐藏所有二级列表
            subMenus.forEach(function(menu) {
                if (menu.id !== targetSubMenuId) {
                    menu.style.display = 'none';
                }
            });
            // 切换目标二级列表的显示状态
            if (targetSubMenu) {
                // 如果目标列表是隐藏的,就显示它;如果已经是显示的,就隐藏它(实现切换效果)
                if (targetSubMenu.style.display === 'block') {
                    targetSubMenu.style.display = 'none';
                } else {
                    targetSubMenu.style.display = 'block';
                }
            }
        });
    });
    // (可选) 点击页面其他地方关闭菜单
    document.addEventListener('click', function(event) {
        // 如果点击的不是一级链接,也不是二级菜单
        if (!event.target.closest('a[data-id]') && !event.target.closest('.sub-menu')) {
            subMenus.forEach(function(menu) {
                menu.style.display = 'none';
            });
        }
    });
});
  1. 引入JS文件:在你的模板的公共文件(通常是 head.htm)的 <head><body> 标签结束前,加入以下代码来引入你刚创建的JS文件。
<script src="{dede:global.cfg_templets_skin/}/js/dropdown_menu.js"></script>

请确保 {dede:global.cfg_templets_skin/} 路径正确,它指向你的模板目录。

至此,方法二也完成了,刷新网站,点击一级栏目,就能看到二级栏目下拉效果,并且URL不会改变。


总结与选择建议

特性 方法一 (纯CSS) 方法二 (JavaScript)
实现复杂度
代码量
URL变化 是 (会添加锚点)
JS依赖
交互灵活性 一般
推荐度 ⭐⭐⭐⭐⭐ (首选) ⭐⭐⭐⭐

给你的建议

  • 如果你的网站追求简洁、高效,且不介意URL有微小的变化,强烈推荐使用方法一(纯CSS),它是最“干净”的解决方案。
  • 如果你对用户体验有更高要求,不希望URL有任何变化,或者计划在未来添加更复杂的交互效果,那么方法二(JavaScript)是不二之选,它更现代,也更灵活。

希望这个详细的教程能帮助你成功实现织梦CMS的二级栏目点击下拉功能!

-- 展开阅读全文 --
头像
C语言学生成绩管理系统如何设计与实现?
« 上一篇 02-18
dede me其他参数具体指哪些?
下一篇 » 02-18

相关文章

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

目录[+]