在自定义 WordPress 主题的页面更改时保持手风琴子菜单打开

Keep Accordion Sub-menu Open on Page Change in Custom WordPress Theme

我有一个客户站点,它要求侧边菜单像手风琴一样,子菜单在单击父菜单后下拉,并在父菜单或任何子菜单处于活动状态时保持打开状态。菜单是在 PHP 中创建的,其中的按钮内容取自服务部分。

菜单是自定义主题的一部分,已插入到多个页面模板中。作为主题的一部分,我想避免更改模板 php 代码。 (不确定主题将多久更新一次)我已经尝试过 css 和 jQuery 但到目前为止只能设法在 onclick 后短暂打开子菜单,然后在页面加载时消失。

您可以在 https://www.birchandco.com 看到该站点 - 目前处于悬停状态,以便访问者可以导航。一旦与 onclick 一起正常工作,这将被删除。

PHP 模板:

<div class="home_services">
    <?php 
        $ser= new WP_Query(array(
            'post_type'=>'service',
            'posts_per_page' => -1, 
            'orderby' => 'name',
            'order' => 'ASC',                                   
            'meta_query' => array(
                array(
                    'key' => '_is_ns_featured_post',
                    'value' => 'yes',
                )
            )                                   
        ));

    ?>
    <ul class="service_list">
        <?php 
            if($ser->have_posts()) :
                while($ser->have_posts())  : $ser->the_post();
        ?>
        <li class="item">
            <a href="<?php the_permalink(); ?>"><?php the_title();?> <i class="fa fa-angle-double-right" aria-hidden="true"></i></a>
            <?php if(get_the_terms(get_the_ID() , 'service_category')[0]->term_id) {?>
                <ul class="submenu">
                    <?php
                        $args = array(
                            'post_type' =>'service',                                                    
                            'orderby' => 'name',
                            'order' => 'ASC',                                                                                       
                            'post__not_in' => array(get_the_ID()),
                            'tax_query' => array(
                                array(                      
                                    'taxonomy' => 'service_category',
                                    'field' => 'term_id',                                                       
                                    'terms' => get_the_terms(get_the_ID() , 'service_category')[0]->term_id
                                )
                            )
                        );
                        $query = new WP_Query( $args ); 
                        $loop = new WP_Query( $args );
                        if( $loop->have_posts() ): 
                            while ( $loop->have_posts() ) : $loop->the_post();
                        ?>
                        <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
                        <?php
                        endwhile; wp_reset_postdata();
                        endif;
                        ?>
                </ul>           
            <?php } ?>
        </li>
        <?php
        endwhile;
        wp_reset_postdata(); 
        endif;
        ?>
    </ul>

</div>

CSS

这是子菜单当前悬停状态的CSS

.home_services ul.service_list > li:hover ul.submenu{
display: block;
opacity:1;
visibility:visible;}

JQuery

这是我设法开始工作的代码,但它只切换子菜单。一旦执行了 onclick 事件并加载了页面,子菜单就会消失。

jQuery(document).ready(function($){
var body = $('body');
$('.home_services ul.service_list li a').on('click', 
function(event){
    event.preventDefault();
    // create accordion variables
    var accordion = $(this);
    var accordionContent = accordion.next('.home_services 
 ul.service_list > li ul.submenu');

    // toggle accordion link open class
    accordion.toggleClass("open");
    // toggle accordion content
    accordionContent.slideToggle(250);

});
});

任何帮助将不胜感激。

我看到了一个可能的 jquery 解决方案,但我不确定如何将下面的代码应用到我的情况中。如果您能提供帮助,我们将不胜感激。

$('.home_services ul.service_list li a').click(function(e){
  ... 

  localStorage.setItem("activeSubMenu", $(this).text());
  });
  On page load, read the localStorage and expand the menu (if found):
  $(document).ready(function(){
var activeItem = localStorage.getItem("activeSubMenu");
if(activeItem){
    $('.home_services ul.service_list li a').filter(function() {
        return $(this).text() == activeItem;
    }).slideToggle();
 }
 });

没有回答你的问题。但是尝试

<div class="container">
  <div class="panel-group" id="accordionMenu" role="tablist" aria-multiselectable="true">
    <div class="panel panel-default">
      <div class="panel-heading" role="tab" id="headingOne">
        <h4 class="panel-title">
        <a role="button" data-toggle="collapse" data-parent="#accordionMenu" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
          Menu 0
        </a>
      </h4>
      </div>
      <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
        <div class="panel-body">
          <ul class="nav">
            <li><a href="#">item 1</a></li>
            <li><a href="#">item 2</a></li>
            <li><a href="#">item 3</a></li>
          </ul>
        </div>
      </div>
    </div>
    <div class="panel panel-default">
      <div class="panel-heading" role="tab" id="headingTwo">
        <h4 class="panel-title">
        <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordionMenu" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
          Menu 1
        </a>
      </h4>
      </div>
      <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo">
        <div class="panel-body">
          <ul class="nav">
            <li><a href="#">item 1</a></li>
            <li><a href="#">item 2</a></li>
            <li><a href="#">item 3</a></li>
            <li><a href="#">item 4</a></li>
          </ul>
        </div>
      </div>
    </div>
    <div class="panel panel-default">
      <div class="panel-heading" role="tab" id="headingThree">
        <h4 class="panel-title">
        <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordionMenu" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
          Menu 2
        </a>
      </h4>
      </div>
      <div id="collapseThree" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree">
        <div class="panel-body">
          <ul class="nav">
            <li><a href="#">item 1</a></li>
            <li><a href="#">item 2</a></li>
            <li><a href="#">item 3</a></li>
            <li><a href="#">item 4</a></li>
          </ul>
        </div>
      </div>
    </div>


    <div class="panel panel-default">
      <div class="panel-heading" role="tab" id="headingFour">
        <h4 class="panel-title">
        <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordionMenu" href="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
          Menu 3
        </a>
      </h4>
      </div>
      <div id="collapseFour" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingFour">
        <div class="panel-body">
          <ul class="nav">
            <li><a href="#">item 1</a></li>
            <li><a href="#">item 2</a></li>
          </ul>
        </div>
      </div>
    </div>

  </div>
</div>

在页面加载时,测试 URL 是否包含手风琴链接到的路径之一。如果是这样,请打开手风琴。像这样:


(function($) {

  $(document).ready(function() {

    // Get the current path (for instance, "/service/contesting-a-will-2/")
    var pathName = window.location.pathname;

    // This is a bit complex, but we're concatenating the pathName variable
    // into your selector so we can find a match and toggle the "open" class
    $('.home_services ul.service_list li a[href*="' + pathName + '"]').toggleClass('open');
  });

})(jQuery);

请注意,我还没有对此进行测试,但总体思路只是将手风琴中的 href 属性与我们从 URL 中创建的 pathname 变量相匹配然后打开手风琴项目。添加 [href*=... 表示 "select all tags that contain" 然后我们传入从 window.location.pathname.

获得的路径

在所有条件相同的情况下,这应该会在页面完成加载时打开手风琴,这基本上实现了页面加载时 "being open" 的目标。

我设法找到了一个解决方案,让子菜单在页面更改时保持打开状态。我删除了现有菜单的 PHP 代码并将其替换为

`<?php //echo do_shortcode("[widget id=nav_menu-3]"); ?>` 

此 [widget id=nav_menu-3] 简码是通过小部件简码创建器插件创建的。我使用 WordPress 菜单系统构建菜单,然后通过导航菜单小部件访问菜单并将其添加到简码部分,以便为小部件创建简码。上面的代码允许您将短代码添加到 PHP 模板。

这使我能够将 WordPress 菜单添加到自定义页面模板中。下一步是设置菜单样式,使其看起来像原始菜单,然后通过 CSS 定位当前菜单项、父菜单和子菜单,以便子菜单在页面更改时保持打开状态。请参阅下面的代码

`/*--- show or hide sub navs based on the parent menu item or the current menu item
----------------------------------------------- */

.widget_nav_menu ul li.current-menu-item ul.sub-menu {display:block;}
.widget_nav_menu ul li.current-menu-item ul.sub-menu li ul.sub-menu 
{display:none;}

.widget_nav_menu ul li.current-menu-parent ul.sub-menu {display:block;}
.widget_nav_menu ul li.current-menu-parent ul.sub-menu li ul.sub-menu 
{display:none;}
.widget_nav_menu ul li.current-menu-parent ul.sub-menu li.current-menu-item 
ul.sub-menu {display:block;}

.widget_nav_menu ul li.current-menu-parent ul.sub-menu li.current-menu-item 
ul.sub-menu {display:block;}
.widget_nav_menu ul li.current-menu-parent ul.sub-menu li.current-menu-item 
ul.sub-menu li ul.sub-menu {display:none;}`

之后,我在parent中添加了一个伪元素(双箭头)来表示有子菜单。

`/*Sub-Menus Pseudo Element - Add to Customise Header
--------------------------------------------- */

ul#menu-services.menu li a:after {
    content: '»';
    font-size: 31px;
    float: right;
  transform: rotate(90deg); -- Turns arrows around so point downwards.
}`