node.js + jade + express: How can I create a navigation that will set class active if the path matches

前端 未结 7 824
刺人心
刺人心 2021-01-31 06:31

I have come up with the following code but the problem is, there will be duplication of the anchor tag for each menu item.Is there a better way to do this?

              


        
相关标签:
7条回答
  • 2021-01-31 06:39

    You can pass the pageName in the data.

    each menu in ["Home", "Dashboard", "Contact", "About"]
        if (menu == pageName)
          li.active
            a(href="/#{menu}")= menu
        else
          li
            a(href="/#{menu}")= menu
    

    You can call render

    res.render("index", { pageName: 'Home'})
    
    res.render("index", { pageName: 'Dashboard'})
    
    res.render("index", { pageName: 'Contact'})
    
    0 讨论(0)
  • 2021-01-31 06:42

    Very flexible without duplication:

    ul
      each menuitem in [{title:'Home',url:'/'},{title:'About',url:'/about'},{title:'Contact',url:'/contact'}]
        if (menuitem.title == title)
          li.active
            a.active(href=menuitem.url) #{menuitem.title}
        else
          li
            a(href=menuitem.url) #{menuitem.title}
    

    You need to set the page's current title.

    0 讨论(0)
  • 2021-01-31 06:45

    I think it's better to set a body class to current path like so

    body(class = currentPath)
    

    So you can then use selectors such as

    body.home .nav li.home, body.dashboard .nav li.dashboard {
      Style when current path
    }
    

    These selectors can be reduced to the minimal 'body.path .path' but it may be not isolated enough.

    This will also be useful in the client side logic as this selectors could be used to determine the path in your JavaScript with something like

    $("body.home").doSomethingSpecificToHome
    

    This way your template has lot less logic.

    Now, I don't think there is a way to set "currentPath" automatically depending on the URL. An helpers based on a 'url':'path' may be useful.

    0 讨论(0)
  • 2021-01-31 06:46

    Here's an alternative that provides more flexibility in terms of anchor text and href than Peter's solution.

    nav
      // suppose title local denotes the active nav item
      - var nav = {}; nav[title] = 'active'
      ul
        // pass title to li class via nav object
        li(class='#{nav.Home}')
          // different href and anchor text
          a(href='/') Home
        li(class='#{nav.About}')
          a(href='/about') About
        li(class='#{nav.Contact}')
          a(href='/contact') Contact
    

    The caveat is that those li that are not active will have an undefined class, which does no harm in most cases.

    0 讨论(0)
  • 2021-01-31 06:49

    Found this in another question that was similar:

    Use a ternary at each "li"

    ul
        li(class=(title === 'Home' ? 'active' : ''))
            a(href='#') Home
        li(class=(title === 'Dashboard' ? 'active' : ''))
            a(href='#') Dashboard
    

    You can setup your routes to pass the "menu" value instead of using "title" if you want:

    exports.index = function(req, res) {
        res.render('index', {title: 'Home', menu: 'Home'});
    }
    
    0 讨论(0)
  • 2021-01-31 06:53

    This has a little less duplication.

    ul.nav
      each name in ["Dashboard", "About", "Contact"]
        if (menu=="Home")
          li.active
            a(href="#")= name
        else
          li
            a(href="#")= name
    

    Adding the active class might be better just done in javascript or perhaps you can get the presentation you need with the straight CSS a:active selector.

    0 讨论(0)
提交回复
热议问题