响应式菜单问题

3

我创建了一个响应式菜单,但它有一些奇怪的行为。这是一个示例fiddle

$('ul.page-menu-nav').each(function () {
  var $ul = $(this);
  var $links = $(this).find('a');
  var $active = $($links.filter('[href="' + location.hash + '"]')[0] || $links[0]);

  $active.addClass('active');

  var $content = $($active[0].hash);

  $links.not($active).each(function () {
    $(this.hash).hide();
  });

  // Bind the click event handler
  $(this).on('click', 'a', function (e) {
    debugger;
    if($(this).parent().hasClass('icon')) {
      return;
    }

    $ul.removeClass('responsive');
    $active.removeClass('active');
    $content.hide();

    $active = $(this);
    $content = $(this.hash);

    $active.addClass('active');
    $content.show();


    e.preventDefault();
  });
});


function toggleMenu() {
  var $nav = $("#myTopnav");

  if ($nav.attr('class') == "page-menu-nav clearfix") {
    $nav.addClass('responsive');
  } else {
    $nav.removeClass();
    $nav.addClass('page-menu-nav clearfix');
  }
}
.clearfix:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}
.clearfix { display: inline-block; }
/* start commented backslash hack \*/
* html .clearfix { height: 1%; }
.clearfix { display: block; }
/* close commented backslash hack */


ul.page-menu-nav {
  list-style-type: none;
  margin: 0;
  padding: 0;
  color:#333;
  border-bottom: 3px solid #e6e6e6; 
  min-height: 48px;
}
ul.page-menu-nav li a.active {
  border-bottom: 3px solid #337ab7;
}

ul.page-menu-nav li {float: left;}

ul.page-menu-nav li a {
  display: inline-block;
  color:#333;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
  margin-bottom:-3px;
  position:relative;
}

ul.page-menu-nav li a:hover {
  border-bottom: 3px solid #337ab7;
}

ul.page-menu-nav li.icon {display: none;}

@media screen and (max-width:680px) {
  ul.page-menu-nav li:not(:first-child) {display: none;}
  ul.page-menu-nav li.icon {
    float: right;
    display: inline-block;
  }
}

@media screen and (max-width:680px) {
  ul.page-menu-nav.responsive {position: relative;}
  ul.page-menu-nav.responsive li.icon {
    position: absolute;
    right: 0;
    top: 0;
  }
  ul.page-menu-nav.responsive li {
    float: none;
    display: inline;
  }
  ul.page-menu-nav.responsive li a {
    display: block;
    text-align: left;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="page-menu-nav clearfix" id="myTopnav">
  <li><a class="active" href="#home">Publish</a></li>
  <li><a href="#news">Post Activity</a></li>
  <li><a href="#contact">Content Library</a></li>
  <li><a href="#about">Post Calendar</a></li>
  <li><a href="#about">Profile Manager</a></li>
  <li class="icon">
    <a href="javascript:void(0);" style="font-size:15px;" onclick="toggleMenu()"></a>
  </li>
</ul>

当响应式模式时,我需要显示活动项目,目前每当选择其他项目时,Publish始终显示。

实现这一点的最佳方法是什么?


我猜我可以使用prepend,但这会影响列表的顺序。 - R4nc1d
您可以为列表项提供顺序ID,然后在响应式模式下使用prepend和ID进行重新排序,以便在非响应式模式下重新排列。 - Dex Dave
2个回答

1
请查看下面的代码片段。它按照您的要求正常工作。

$('ul.page-menu-nav').each(function () {
  var $ul = $(this);
  var $links = $(this).find('a');
  var $active = $($links.filter('[href="' + location.hash + '"]')[0] || $links[0]);

  $active.addClass('active');

  var $content = $($active[0].hash);

  $links.not($active).each(function () {
    $(this.hash).hide();
  });

  // Bind the click event handler
  $(this).on('click', 'a', function (e) {
    debugger;
    if($(this).parent().hasClass('icon')) {
      return;
    }

    $ul.removeClass('responsive');
    $active.removeClass('active');
    //$active.parent().hide();
    //$content.hide();

    $active = $(this);
    //$content = $(this.hash);

    $active.addClass('active');
    //$active.parent().show();

    $("#myTopnav li:eq(0)").before($(this).parent());
    e.preventDefault();
  });
});


function toggleMenu() {
  var $nav = $("#myTopnav");

  if ($nav.attr('class') == "page-menu-nav clearfix") {
    $nav.addClass('responsive');
  } else {
    $nav.removeClass();
    $nav.addClass('page-menu-nav clearfix');
  }
}
.clearfix:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}
.clearfix { display: inline-block; }
/* start commented backslash hack \*/
* html .clearfix { height: 1%; }
.clearfix { display: block; }
/* close commented backslash hack */


ul.page-menu-nav {
  list-style-type: none;
  margin: 0;
  padding: 0;
  color:#333;
  border-bottom: 3px solid #e6e6e6; 
  min-height: 48px;
}
ul.page-menu-nav li a.active {
  border-bottom: 3px solid #337ab7;
}

ul.page-menu-nav li {float: left;}

ul.page-menu-nav li a {
  display: inline-block;
  color:#333;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
  margin-bottom:-3px;
  position:relative;
}

ul.page-menu-nav li a:hover {
  border-bottom: 3px solid #337ab7;
}

ul.page-menu-nav li.icon {display: none;}

@media screen and (max-width:680px) {
  ul.page-menu-nav li:not(:first-child) {display: none;}
  ul.page-menu-nav li.icon {
    float: right;
    display: inline-block;
  }
}

@media screen and (max-width:680px) {
  ul.page-menu-nav.responsive {position: relative;}
  ul.page-menu-nav.responsive li.icon {
    position: absolute;
    right: 0;
    top: 0;
  }
  ul.page-menu-nav.responsive li {
    float: none;
    display: inline;
  }
  ul.page-menu-nav.responsive li a {
    display: block;
    text-align: left;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="page-menu-nav clearfix" id="myTopnav">
  <li><a class="active" href="#home">Publish</a></li>
  <li><a href="#news">Post Activity</a></li>
  <li><a href="#contact">Content Library</a></li>
  <li><a href="#about">Post Calendar</a></li>
  <li><a href="#about">Profile Manager</a></li>
  <li class="icon">
    <a href="javascript:void(0);" style="font-size:15px;" onclick="toggleMenu()"></a>
  </li>
</ul>


谢谢,这个效果很好,如果ul保持响应式模式,那么如果我将其更改为正常屏幕尺寸,项目会跳来跳去。 - R4nc1d

1
除了Rahul的回答之外 - 重新排列列表的方法: 您可以为列表项提供自定义数据属性
var menu = $("ul.page-menu-nav");
var mList = $(menu).find('li');
$(mList).each(function(i){
    $(this).attr("data-sort", i);
});

在非响应式模式下,使用排序来恢复原始顺序

$(mList).detach().sort(function() {
  return $(mList).data('sort');  
});

$(menu).append($(mList));

实现示例:

var smallBreak = 680; // Your small screen breakpoint in pixels
$( window ).resize(function() {
    if ($(window).width() > smallBreak) {
        $(mList).detach().sort(function() {
          return $(mList).data('sort');  
        });

        $(menu).append($(mList));
    }
});

祝你好运 :)


我喜欢自定义属性的想法,但问题是每次都必须在window.resize上运行它。这意味着排序将每次都运行。 - R4nc1d
在 resize 函数中,你可以找到一种方法来检查你的菜单是否处于响应模式,然后只有在非响应模式下实现你的排序。 - Dex Dave
是的,我正在做那个。 - R4nc1d

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