什么原因会导致在for循环的不同迭代中,HTML和脚本表现不同?

10

我正在尝试构建一个侧边导航栏,在其中列出类别,点击类别时,相应的子类别列表会显示在该类别的下方。如果再次单击该类别,则子列表将收缩。

因此,我正在对类别对象运行循环。在这个外部循环内,我包含了一个内部循环来列出子类别,并使用一个脚本隐藏子菜单,只有在单击类别时才滑动切换它。我使用django模板标记为我的html元素动态分配类名并引用它们在脚本中。因此,所有循环迭代完成后,有一个子类别列表和每个类别的专用脚本,并且它们具有唯一的类名,因此没有重叠的机会。所以奇怪的是,这对大多数类别都起作用,但是其中一些类别及其子菜单保持打开状态,当单击该类别时页面重新加载。

我不明白,什么原因会导致完全相同的代码(在for循环中运行)表现如此不同?

这是我的代码:

{% load staticfiles %}
{% load i18n pybb_tags forumindexlistbycat %}
{% catindexlist as catindexlisted %}

{% block body %}<div class="col-sm-12 col-md-12 col-xs-12 col-lg-12 body-container leftsidenavigator" style="margin-top:15px;">
    <div class="col-sm-12 col-md-12 col-xs-12 col-lg-12 leftsidenavigator-inner" style="padding:0px;">
         <h2><center>Categories</center></h2>
             <ul class="catindexlist catlistcat nav-collapse89">
                   {% for category in catindexlisted %}
                         <li class="catindexlistitem category-name{{category.name}}{{category.name}}" style="font-weight:600;padding-right:20px;"><a href="">{{category.name}}</a></li>
                         <ul style="padding:0px;" class="nav-collapse88">
                         {% for forum in category|forumindexlistbycat %}
                               <li class="catlistforum{{category.name}}{{category.name}} forum-name" style="padding-right:10px;"><a href="{{ forum.get_absolute_url }}">{{forum.name}}</a></li>
                         {% endfor %}</ul><script>

                         $(function() {
                              $(".catlistforum{{category.name}}{{category.name}}").hide();
                                    $(".category-name{{category.name}}{{category.name}} a").click(function(e) {
                                     e.preventDefault();
                                     $(".catlistforum{{category.name}}{{category.name}}").slideToggle();
                                          if(!($(this).parent('li').siblings('div').children('ul').children('div').is(":visible"))){
                                              $(this).parent('li').siblings('div').children('ul').children('div').is(":visible").slideToggle();
                                          }});
                                      })
                                </script>
                           {% endfor %}
                           </ul>
                      </div>
                      </div>
                  {% endblock %}
     {% block theme_script %}<script src="{% static "pinax/js/theme.js" %}"></script>{% endblock %}

1
你能提供一个最小的代码示例吗? - TomLingham
1
请提供您的HTML代码。 - Sunil Kumar
1
在不工作的类别名称中有任何模式吗?例如空格、非英文字符等。请注意,您需要确保它是一个有效的字符串,可以在此处使用,例如 $(".catlistforum{{category.name}}{{category.name}}"). 我认为您应该使用PK而不是名称。 - trinchet
1
请提供生成的HTML代码示例,或者链接到可以看到此效果的页面。正如@trinchet所说,可能会出现选择器/类名冲突的模式(或名称包含无效字符,或为空等)。 - TylerY86
4个回答

1

类别名称是否可能包含空格?

小提示:您的代码实践不佳。在我看来,您应该将JavaScript代码移出for循环,并删除{{ category_name }}类。单击catindexlistitem应将hidden类(我注意到您正在使用bootstrap)切换到其子ul。

通过添加更通用的事件监听器,可以简化您的代码,并使用CSS提高性能。如果您想添加效果,则仍然可以使用css3。


1
最可能的原因是使用{{category.name}}作为类名。代码片段没有显示category.name接受什么值,我猜它可以是用户输入?请参见属性值部分的命名规则,了解类名有效的内容。
可以使用模板标签slugify({{category.name|slugify}})来解决问题,但我的建议是尝试重新设计解决方案。

0
尝试在外部for循环后编写javascript函数,有时这可能会重叠并重定向。此外,请尝试在“li”内提供类别名称之间的空格。

0
我的建议是通过创建一个单一的函数来处理所有的点击事件,来清理你的JS代码。你已经在点击事件上使用了类,那么为什么不让一个函数来处理所有的点击事件呢?
<script>
  $(function() {
    // Hide all elements with a class starting with catlistforum
    $('[class^="catlistforum"]').hide();

    // Assign clicks to all links whose parent has a class starting with catlistforum
    // (Though why are you hiding the parents? How will they click the links?)
    $('[class^="catlistforum"] a').on("click", function(e) {
      e.preventDefault();

      // Delegate slideToggle to each click target
      $(e.target).slideToggle();

      // This seems redundant, but hopefully it will behave the way you want it to behave
      if(!($(e.target).parent('li').siblings('div').children('ul').children('div').is(":visible"))) {
        $(e.target).parent('li').siblings('div').children('ul').children('div').is(":visible").slideToggle();
      }
    });
  })
</script>

当然,如果我是你,我会定义两个新的类(例如catlistforum-hidecatlistforum-toggle),将其应用于我想要隐藏和切换的所有元素。

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