突出显示侧栏中的当前菜单项

时间:2012-08-16 15:10:16

标签: jquery django django-templates twitter-bootstrap

我在Twitter Bootstrap上使用django。我当前的观点类似于examples provided之一。查看示例,可以想象用户单击侧栏中的一个链接以查看不同的视图,每个视图都使用相同的侧边栏框架。可以想象,选择的链接将像使用代码的示例一样突出显示:

<li class="active"><a href="/sample/link/here/">Link</a></li>

活动类需要附加到正确的菜单项。我怎么能指定这个&#34;活跃&#34;类到正确的菜单项?最初,我尝试使用视图中的变量为jquery分配它:

$(document).ready(function() {
    $("#{{ current_view }}_nav").addClass('active');
});

<li id="linkone_nav"><a href="/sample/link/here/">Link</a></li>

这看起来很麻烦。它要求我从视图中将id传递给模板。还有很多要管理的ID。是否有更好/更首选的方式来分配此活动类?

7 个答案:

答案 0 :(得分:7)

我认为您在示例代码中使用#作为href会使问题蒙上阴影。我假设您的真实场景是实际的真实链接,并根据活动URL自动突出显示它们。如果这是正确的,那么就这样做:

{% url something as url %}
<li{% if request.path == url %} class="active"{% endif %}><a href="{{ url }}">Link1</a></li>

其中,“something”是urlpattern的名称或视图的虚线路径等。这假设你正在反转URL,显然,如果你使用静态URL,你只需硬编码它:

<li{% if request.path == "/my/full/url/path/" %} class="active"{% endif %}><a href="/my/full/url/path/">Link1</a></li>

答案 1 :(得分:7)

如果您已将项目组织到由其他模板扩展的base.html模板中,例如appname/pagename.html,您可以使用以模板为中心的方法突出显示活动导航元素。

这种方法为您提供了一些解耦优势,我在本答案的最后详细说明了这一点。

我发现这种方法对于处理大多数或全部网站保持相同的广泛导航项非常有用。它可能不是更详细的导航元素的合适解决方案,例如渲染从数据存储中收集的项目的动态列表。

base.html模板中,为每个导航元素添加一个块,为块提供唯一的名称:

<ul class="nav">
  <li class="{% block navbar_class-home %}{% endblock %}">
    <a href="#">Home</a>
  </li>
  <li class="{% block navbar_class-about %}{% endblock %}">
    <a href="#">About</a>
  </li>
  <li class="{% block navbar_class-pricing %}{% endblock %}">
    <a href="#">Pricing</a>
  </li>
</ul>

appname/pagename.html模板中,如果您希望其中一个导航元素显示为活动状态,请使用active作为内容覆盖相应的阻止。例如,要突出显示“关于”项目:

{% block navbar_class-about %} active {% endblock %}

当您使用呈现该模板的视图时,它将呈现如下:

<ul class="nav">
  <li class="">
    <a href="#">Home</a>
  </li>
  <li class=" active ">
    <a href="#">About</a>
  </li>
  <li class="">
    <a href="#">Pricing</a>
  </li>
</ul>

这提供了一个不依赖于JavaScript的初始渲染。 (如果您正在使用单页应用程序,则可以使用JavaScript修改导航栏类。)

对于许多(但不是全部)情况,这可以是视图逻辑的更好的分离表示:

  • 您可以修改视图以将网站导航数据附加到模板上下文,但这样做会将演示文稿强烈地耦合到视图层,从而使创建可重用应用程序或集成第三方应用程序变得更加困难。

    视图已经在选择命名模板,这意味着您已经将一些与导航相关的信息传递给模板层。这可能就是你所需要的一切。

  • 您可以使用模板上下文处理器来获取有关视图的一些信息,但这只是将强耦合移动到系统的另一层,而不是停留在模板层中。

答案 2 :(得分:2)

更好的解决方案,代码更少。和Bootstrap一起玩得很好。只需更改“addClass”查询即可选择菜单项。

在Javascript上,创建此功能:

var highlight_menu = function(path) {
    /* Highlight current link */    
    $('.nav li').removeClass('active');
    $('.nav li:has(a[href="' + path + '"])').addClass('active')
};

在base.html上,使用当前路径调用JS函数:

<script>
    highlight_menu('{{request.path}}');
</script>

答案 3 :(得分:1)

FWIW,Twitter Bootstrap页面本身使用Scrollspy plugin提供此功能。

否则,您只需在菜单中收听点击事件即可。

$('.nav').on('click', 'li:has(a[href^="#"])', function (e) {
  $('.nav li').removeClass('active');
  $(this).addClass('active');
});

答案 4 :(得分:0)

为您的菜单制作一个包含代码段:

<li class="{% if opt=='link1' %} active{% endif %}"><a href="#/?opt=link1">Link1</a></li>
<li class="{% if opt=='link2' %} active{% endif %}"><a href="#/?opt=link2">Link2</a></li>
<li class="{% if opt=='link3' %} active{% endif %}"><a href="#/?opt=link3">Link3</a></li>
...

将其包含在您的基本模板中:

{% include "menu.html" with opt=request.GET.opt %}

如您所见,您无需使用$(document).ready(...)。

不要忘记向TEMPLATE_CONTEXT_PROCESSORS添加请求:

TEMPLATE_CONTEXT_PROCESSORS = (
  # ...
  'django.core.context_processors.request',
  # ...
)

答案 5 :(得分:0)

您可以考虑以下方法来解决Django中的问题。

无需使用javascript即可正常运行。只需使用纯Django,您就应该能够解决大多数需要突出显示菜单选项的情况。

在此示例中,我使用的是Bootstrap 4,但这并不重要。您可以使用自己的CSS,就可以了。这里的想法只是展示使用 request.resolver_match.url_name作为url_name 来实现您所需要的。

{% with request.resolver_match.url_name as url_name %}
   <ul class="navbar-nav mr-auto">
      <li class="{% if url_name == 'your url' %}nav-item active{% else %}nav-item{% endif %}">
       <a class="nav-link" href="{% url 'your url 1' %}">Menu option 1</a>
      </li>
      <li class="{% if url_name == 'your url' %}nav-item active{% else %}nav-item{% endif %}">
       <a class="nav-link" href="{% url 'your url 2' %}">Menu option 2</a>
      </li>
   </ul>
{% endwith %}

答案 6 :(得分:0)

我为此使用了一个 simple_tag。也许有人会觉得它有帮助。

创建一个文件 isactive.py 并将其放入应用模板路径级别的 templatetags 目录中。

from django import template
from django import urls
register = template.Library()

@register.simple_tag
def isactive(page_name, request_url):
    rev_url = ''
    try:     
        rev_url = urls.reverse(page_name)
    except:
        return ''
    if (rev_url == request_url):
            return 'active'
    return ''

在你的 html 模板中

{% load isactive %}

加载静态后 并在您的菜单中

<a href="{% url 'my_table_list' %}" class="nav-link {% isactive 'my_table_list' request.path %}">

渲染时 - django 正在执行函数 isactive,其中第一个参数是页面的名称,另一个是路径。在 isactive 函数中,名称被解析和比较。当它匹配时,将返回活动字符串并放置在生成的 html 中。 您必须将该调用放入每个导航链接中。

页面名称取自您应用的 urls.py 中的 urlpatterns

urlpatterns = (
    ...
    path("my_table/list/", views.mytableListView.as_view(), name="my_table_list"),
    ....