我正在尝试在Bulma CSS中使用汉堡菜单,但它不起作用。有什么问题吗?

28

我在学习使用Bulma CSS http://bulma.io/

我想为移动用户使用汉堡菜单。我刚刚按照这个页面上的说明操作:http://bulma.io/documentation/components/nav/

但它没有起作用。我需要添加些什么?

实际上,我可以看到汉堡菜单,但当我点击它时它却没反应。

谢谢。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
        <title>test</title>

        <link rel="stylesheet" href="css/bulma.min.css">
        <link rel="stylesheet" href="css/custom.css">
    </head>
    <body>
        <section class="hero is-fullheight is-primary is-bold">
            <!-- Hero header: will stick at the top -->
            <div class="hero-head">
                <header class="nav">
                    <div class="container">
                        <div class="nav-left">
                            <a class="nav-item" href="/">
                                <img src="img/logo.png" alt="Logo">
                            </a>
                        </div>
                        <span class="nav-toggle">
                            <span></span>
                            <span></span>
                            <span></span>
                        </span>
                        <div class="nav-right nav-menu">
                            <a class="nav-item" href="/about">
                                About
                            </a>
                            <a class="nav-item" href="/path">
                                Path
                            </a>
                            <a class="nav-item" href="/blog">
                                Blog
                            </a>
                        </div>
                    </div>
                </header>
            </div>
            <!-- Hero content: will be in the middle -->
            <div class="hero-body">
                <div class="container has-text-centered">
                </div>
            </div>
        </section>
    </body>
</html>

这应该可以直接在bulma css中使用。请检查您是否在正确的路径上有压缩的css文件。您也可以使用CDN选项。bulma的CDN链接在这里 - Parthipan Natkunam
嗯,我确定这是正确的路径。此外,我还尝试了CDN,但对我来说没有用。 - moge
12个回答

41

这个解决方案使用Vue.js在移动视图时切换bulma导航组件。我希望这能帮助其他寻找替代方案的人。

JS

首先,我添加了Vue.js的cdn,可以从https://unpkg.com/vue找到,并在JavaScript中包含了Vue的一个实例。

new Vue({
  el: '#app',
  data: {
    showNav: false
  }
});

HTML

a. 将导航部分用"app"元素包装起来,以使其具有响应性(这对应于Vue实例的"el"属性)。

<div id="app"> ... </div>
.navbar-burger使用v-on指令更新,以侦听单击事件并切换数据属性showNav。
<div class="navbar-burger" v-on:click="showNav = !showNav" v-bind:class="{ 'is-active' : showNav }">

c. 使用 v-bind: 指令更新 .navbar-menu,以便通过 showNav 属性的结果反应地更新 class 属性。

<div class="navbar-menu" v-bind:class="{ 'is-active' : showNav }">

解决方案

我已经在这个jsfiddle中包含了整个解决方案。


3
来自谷歌搜索并想要为您的答案增加内容,因为Bulma中的nav很快将被弃用。 如果您正在使用navbar示例,则只需将:class="{ 'is-active': showNav }" @click="showNav = !showNav"添加到navbar-burger标记,并将:class="{ 'is-active': showNav }"添加到navbar-menu即可。 - JeffBeltran
谢谢 @JeffBeltran!我已经更新了我的 解决方案,使用了最新版本的bulma.css和导航栏组件。 - tbonz
你能否在你的解决方案中添加代码,使得当导航栏被点击时它可以下拉?我尝试在 navbar-menu 周围添加一个过渡包装器,但似乎无法使其正常工作。 - doublea
@doublea 我尝试过添加这个功能,但发现你不能对具有 display: none 属性的元素应用过渡效果。CSS 不是我的强项,希望其他人能提供解决方案。 - tbonz
谢谢您的回答。我使用它来适应Angular的逻辑,并在下面发布了它。 - Riscie

10
这可能是文档中给出的示例存在问题,我通过为.nav-toggle和.nav-menu添加id来使其正常工作。
添加代码如下:<span id="nav-toggle" class="nav-toggle"><div id='nav-menu' class="nav-right nav-menu"> 在此处可查看jsfiddle。因此,要使示例正常工作,您需要为相应的元素添加“id”。我建议您深入研究文档。

我已经尝试过了,但是没有成功。我想知道的是,我应该导入的文件只有bulma.css吗?我的意思是,我以为我应该导入jquery或其他东西。 - moge
1
嗯...你应该导入jQuery和bulma.js。导航的点击事件在bulma.js中。 - semuzaboi
终于成功了!非常感谢。我误解了Bulma CSS仅仅是CSS的工作方式。 - moge
我做到了!非常感谢 :) - moge
4
遗憾的是,你的示例依赖于jQuery。 - Antonio Brandao

6
(function() {
    var burger = document.querySelector('.nav-toggle');
    var menu = document.querySelector('.nav-menu');
    burger.addEventListener('click', function() {
        burger.classList.toggle('is-active');
        menu.classList.toggle('is-active');
    });
})();

4
虽然这段代码可能回答了问题,但是提供关于它如何解决问题以及为什么解决问题的额外背景信息,将会提高答案的长期价值。 - Donald Duck
哦,抱歉,我刚开始在这里帮助人们...因此,我将尝试为任何人解释(考虑长期):我们需要查询(还记得jQuery吗?不需要再使用它)nav-toogle和nav-menu,将它们存储在变量中(请阅读关于引用类型的内容),之后开始监听此处的“汉堡包”上的事件,即鼠标单击或触摸屏幕。当发生单击时,它将切换类“is-active”。该函数是一个自执行函数,这意味着它从页面加载的那一刻开始执行。 - Ruggero Rebellato
@RuggeroRebellato:为什么要使用立即调用函数表达式(IIFE)?它的使用是否允许在页面加载时立即使用此功能?如果是这样,为什么不只使用onLoad/load事件监听器呢? - DeltaFlyer

3
您可以不使用jquerybulma.js来使其工作。只需使用自己的javascript,在单击nav-toggle时将is-active添加到nav-menu类即可。

nav-menu已折叠。

nav-menu is-active已展开。

我认为有些人可能正在寻找一个没有jquery的解决方案,所以这里将会有所有内容。


3
为了使切换点击事件起作用,只需添加下面的js代码。您可以创建一个JS文件夹,然后将bulma.js文件放入其中。

// source: https://gist.github.com/Bradcomp/a9ef2ef322a8e8017443b626208999c1
(function () {
    var burger = document.querySelector('.burger');
    var menu = document.querySelector('#' + burger.dataset.target);
    burger.addEventListener('click', function () {
        burger.classList.toggle('is-active');
        menu.classList.toggle('is-active');
    });
})();

At the end of your html page add the script. ex:
<script async type="text/javascript" src="./js/bulma.js"></script>


2

有一个更简单的方法!在介绍这个方法之前,看起来您的Html存在一些问题。

第一个问题。您没有按照文档建议设置导航栏结构。如果您将nav-left替换为navbar-brand,它将为您处理一些Html。在您的代码示例中,您的徽标是作为nav-item放置在nav-left中的。而navbar-brand正好可以解决这个问题。您所做的可能有效,但我不确定那样做会产生什么影响。根据文档:

"navbar-brand位于左侧,始终可见,通常包含标志和可选链接或图标"

因此,如果您将其移至容器的级别,并在其中,只需将徽标放在第一个navbar-item中即可。接下来是将“navbar-burger”放入“navbar-brand”中。

navbar-burger是一个汉堡菜单,仅在移动设备上显示。它必须出现在navbar-brand的最后一个子元素位置。

设置完成后,您将希望将要折叠的菜单项放在navbar-menu中。此容器应该是navbar-brand的同级元素,因此它们应该在同一级别上。因此,在您的容器div中,您的代码应该像这样:

<nav class="navbar">
    <div class="navbar-brand">
      <a class="navbar-item" href="/">
        <img src="../assets/icon.png" alt="something">
      </a>

      <div class="navbar-burger burger" data-target="Options">
        <span></span>
        <span></span>
        <span></span>
      </div>
    </div>

    <div class="navbar-menu" id="Options">
      <div class="navbar-end">
        <a class="nav-item" href="/about">About</a>
        <a class="nav-item" href="/path">Path</a>
        <a class="nav-item" href="/blog">Blog</a>
      </div>
    </div>
  </nav>

最后一步是:你需要将汉堡菜单的 data-target 设为 navbar-menu 的 ID。文档中并没有很清晰地说明这一点。不管怎样,当你做完这些更改后,文档中的 JavaScript 代码应该可以正常工作!
我知道这个问题已经问了很久,但我希望这能对某些人有所帮助。 Bulma 文档:http://bulma.io/documentation/components/navbar/

不幸的是,它并没有,因为即使使用这个也似乎无法工作。恐怕 Bulma 本身就有问题。 - Okarin
1
@Okarin 嗯,我的只需要以上更改就可以正常工作。我在处理这个问题时发现了另一个问题:我没有在HTML标头中设置我的视口元字段。如果您没有设置视口,则不会使用内置的响应能力。尝试将以下内容添加到html文件的标题中:但是,我需要看一下您的代码才能真正帮助您。 - AndyBobandy

2

bulma包不提供任何javascript功能。因此,您需要自己编写代码。但您不需要太复杂的内容。只需将要切换的元素的id与汉堡包的data-target设置为相同即可。像这样:

<a role="button" class="navbar-burger" data-target="navMenu" aria-label="menu" aria-expanded="false">
  <span aria-hidden="true"></span>
  <span aria-hidden="true"></span>
  <span aria-hidden="true"></span>
</a>

<div class="navbar-menu" id="navMenu">
  <!-- navbar-start, navbar-end... -->
</div>

将以下 JavaScript 代码片段添加到文件末尾(注意:您不需要更改任何内容):

<script>
  document.addEventListener('DOMContentLoaded', () => {

    // Get all "navbar-burger" elements                                                              
   const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);

    // Check if there are any navbar burgers
    if ($navbarBurgers.length > 0) {

      // Add a click event on each of them
      $navbarBurgers.forEach( el => {
        el.addEventListener('click', () => {

          // Get the target from the "data-target" attribute
          const target = el.dataset.target;
          const $target = document.getElementById(target);
 
          // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
          el.classList.toggle('is-active');
          $target.classList.toggle('is-active');
  
        });
      });
    }  

  });
</script>

就是这样!它有效了!

这些代码块来自文档:https://bulma.io/documentation/components/navbar/#navbar-burger


它可以工作,但有一个打字错误,应该是 '.navbar-burger' 而不是 '.navbar- burger' - user3032538

2

我的简单但功能性的答案:

function toggleBurger() {
    var burger = $('.burger');
    var menu = $('.navbar-menu');
    burger.toggleClass('is-active');
    menu.toggleClass('is-active');
}

在汉堡菜单标签中:

<div class="navbar-burger burger" data-target="navMenu" onclick="toggleBurger()">
            <span></span>
            <span></span>
            <span></span>
        </div>

2

你也可以使用内联 onclick 让它起作用。

<a role="button" onclick="this.classList.toggle('is-active');document.querySelector('#'+this.dataset.target).classList.toggle('is-active');" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="efpnavbar">

1
是的,感谢您将所有不必要过于复杂的示例和“解决方案”整理成有意义的内容... 只需记得将 data-target 更改为您正在使用的内容即可。 - Dániel

2
这里是一个Angular的解决方案: 模板 - 按钮(注意最后两行)
<a
    role="button"
    class="navbar-burger burger"
    aria-label="menu"
    aria-expanded="false"
    data-target="navbarBasicExample"
    [class.is-active]="showBurgerMenu"
    (click)="showBurgerMenu = !showBurgerMenu">

模板 - 菜单(注意最后一行)


<div 
    id="navbarBasicExample" 
    class="navbar-menu" 
    [class.is-active]="showBurgerMenu">

组件(注意showBurgerMenu属性)

import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-navbar',
    templateUrl: './navbar.component.html',
    styleUrls: ['./navbar.component.sass']
})
export class NavbarComponent {
    showBurgerMenu: boolean;
    constructor() {}

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接