悬停时的导航滑动线-当没有项目为“当前”或“选定”时

时间:2018-07-16 22:20:39

标签: javascript jquery html css sass

我以为我会重新撰写这篇文章,因为我本来并没有明确表示自己-对此表示歉意!认为最好是编辑而不是创建新线程。

我的主导航上有一条滑动线,因此将鼠标悬停在该行上会使其从当前位置(应该是当前页面)移动到/滑过该项目。

示例:https://codepen.io/moy/pen/Yjqrqo

我遇到的问题是菜单项上没有current_menu_item类时会中断。

80%的时间将有一个“选定”菜单项,但是在某些情况下,当您使用条款,隐私,联系方式(页脚链接)页面时,没有与之相关的主要导航项。

理想情况下,当没有选定的项目时,我希望线条在悬停时淡入,然后从那里滑动。然后,如果您没有单击任何内容并再次离开菜单,则该行将淡出。但我愿意提出建议。希望有人能帮忙!

$(function() {
    var $el, leftPos, newWidth, $mainNav = $(".site-nav__list");
    $mainNav.append("<div class='site-nav__line'></div>");
    var $magicLine = $(".site-nav__line");
    $magicLine
        .width($(".current-menu-item").width())
        .css("left", $(".current-menu-item a").position().left)
        .data("origLeft", $magicLine.position().left)
        .data("origWidth", $magicLine.width());

    $(".site-nav__list li a").hover(function() {
        $el = $(this);
        leftPos = $el.position().left;
        newWidth = $el.parent().width();
        $magicLine.stop().animate({
            left: leftPos,
            width: newWidth
        });
    }, function() {
        $magicLine.stop().animate({
            left: $magicLine.data("origLeft"),
            width: $magicLine.data("origWidth")
        });
    });
});
/* MIXIN */

@mixin clearfix() {
	
	&:before,
	&:after {
		content: "";
		display: table;
	}
	
	&:after {
		clear: both;
	}
}

/* Body */

body {
  background: #f9f9f9;
  margin: 0;
  padding: 5px 0 0;
}

/* Header */

.page-head {
	background: white;
  border-top: 2px solid #ddd;
	box-sizing: border-box;
  @include clearfix;
	padding: 0 30px;
	position: relative;
	width: 100%;
}

.page-head__logo {
	background-image: none;
	float: left;
	padding: 0;
	text-shadow: none;
	width: 200px;
}

/* Nav */

.site-nav {
	display: block;
  float: right;
	text-align: center;
  width: auto;
}

.site-nav__list {
  list-style: none;
	margin: 0;
	padding: 0;
  position: relative;
  top: auto;
  left: auto;
  width: auto;
}

.site-nav__list li {
	background: none;
  display: inline-block;
	margin: 0;
	padding-left: 0;
	text-transform: uppercase;
	
	&.current-menu-item {}
}

.site-nav__list a {
	box-sizing: border-box;
	display: block;
	font-weight: 900;
	padding: 30px 15px;
	transition: color .15s;
	text-shadow: none;
  
  &:hover {
    color: red;
  }
}

/* Underline */

.site-nav__line {
  background: red;
  content: "";
  display: block;
  height: 2px;
  position: absolute;
  top: -2px;
  left: 0;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="page-head">
    <a href="#" class="page-head__logo">Logo Here </a>
    <nav class="site-nav">
        <ul class="site-nav__list">
            <li class="site-nav__item current-menu-item"><a href="#" class="site-nav__link">Home</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">About</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">Looooonger Title</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">Company</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">About</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">Login</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link amp">Apply</a></li>
        </ul>
    </nav>
</header>

3 个答案:

答案 0 :(得分:3)

当您没有.current-menu-item时,$(".current-menu-item").width()$(".current-menu-item a").position().left将返回undefined,从而崩溃。在这里,我对您的代码没有什么改变。

$(".site-nav__list li a").hover(function() {
        $el = $(this);
        leftPos = $el.position().left;
        newWidth = $el.parent().width();
        $magicLine.stop().animate({
            left: leftPos,
            width: newWidth
        });
    }, function() {
        $magicLine.stop().animate({
            left: $magicLine.data("origLeft"),
            width: $magicLine.data("origWidth")
        });    
    });

使用

$(".site-nav__list li a").hover(function() {
    $el = $(this);
    leftPos = $el.position().left;
    newWidth = $el.parent().width();
    if ($magicLine.width() >0) {
      $magicLine.stop().animate({
        left: leftPos,
        width: newWidth
      });
    } else {
      $magicLine.width(newWidth).css("left", leftPos).fadeIn(3000);
    }
}, function() {
    $magicLine.stop().animate({
        left: $magicLine.data("origLeft"),
        width: $magicLine.data("origWidth")
    });    
});

还有

$magicLine.stop().animate({
    left: $magicLine.data("origLeft"),
    width: $magicLine.data("origWidth")
});

使用

if ($currentMenu.length) {
       $magicLine.stop().animate({
            left: $magicLine.data("origLeft"),
            width: $magicLine.data("origWidth")
        });
       } else {
        $magicLine.fadeOut('slow'); 
       }

$(function(){
	var $el, leftPos, newWidth,
        $mainNav = $(".site-nav__list");
    
    $mainNav.append("<div class='site-nav__line'></div>");
    var $magicLine = $(".site-nav__line"),
        $currentMenu = $(".current-menu-item");
  
    $magicLine
        .width($currentMenu.length ? $currentMenu.width() : 0)
        .css("left", $currentMenu.length ? $currentMenu.find("a").position().left : 0)
        .data("origLeft", $magicLine.position().left)
        .data("origWidth", $magicLine.width());

 $(".site-nav__list li a").hover(function() {
        $el = $(this);
        leftPos = $el.position().left;
        newWidth = $el.parent().width();
        if ($magicLine.width() >0) {
          $magicLine.show().stop().animate({
            left: leftPos,
            width: newWidth
          });
        } else {
          $magicLine.width(newWidth).css("left", leftPos).fadeIn(3000);
        }
    }, function() {
   if ($currentMenu.length) {
       $magicLine.stop().animate({
            left: $magicLine.data("origLeft"),
            width: $magicLine.data("origWidth")
        });
       } else {
        $magicLine.fadeOut('slow'); 
       }
        
            
    });
});
/* MIXIN */

@mixin clearfix() {
	
	&:before,
	&:after {
		content: "";
		display: table;
	}
	
	&:after {
		clear: both;
	}
}

/* Body */

body {
  background: #f9f9f9;
  margin: 0;
  padding: 5px 0 0;
}

/* Header */

.page-head {
	background: white;
  border-top: 2px solid #ddd;
	box-sizing: border-box;
  @include clearfix;
	padding: 0 30px;
	position: relative;
	width: 100%;
}

.page-head__logo {
	background-image: none;
	float: left;
	padding: 0;
	text-shadow: none;
	width: 200px;
}

/* Nav */

.site-nav {
	display: block;
  float: right;
	text-align: center;
  width: auto;
}

.site-nav__list {
  list-style: none;
	margin: 0;
	padding: 0;
  position: relative;
  top: auto;
  left: auto;
  width: auto;
}

.site-nav__list li {
	background: none;
  display: inline-block;
	margin: 0;
	padding-left: 0;
	text-transform: uppercase;
	
	&.current-menu-item {}
}

.site-nav__list a {
	box-sizing: border-box;
	display: block;
	font-weight: 900;
	padding: 30px 15px;
	transition: color .15s;
	text-shadow: none;
  
  &:hover {
    color: red;
  }
}

/* Underline */

.site-nav__line {
  background: red;
  content: "";
  display: block;
  height: 2px;
  position: absolute;
  top: -2px;
  left: 0;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
  <header class="page-head">

    <a href="#" class="page-head__logo">Logo Here </a>

    <nav class="site-nav">
      <ul class="site-nav__list">
        <li class="site-nav__item "><a href="#" class="site-nav__link">Home</a></li>
        <li class="site-nav__item"><a href="#" class="site-nav__link">About</a></li>
        <li class="site-nav__item"><a href="#" class="site-nav__link">Looooonger Title</a></li>
        <li class="site-nav__item"><a href="#" class="site-nav__link">Company</a></li>
        <li class="site-nav__item"><a href="#" class="site-nav__link">About</a></li>
        <li class="site-nav__item"><a href="#" class="site-nav__link">Login</a></li>
        <li class="site-nav__item"><a href="#" class="site-nav__link amp">Apply</a></li>
      </ul>
    </nav>

  </header>
</body>

答案 1 :(得分:1)

就在“关于”列表项之前,添加具有li标签且样式为anchor的{​​{1}}标签即可解决此问题。

display:none

在不属于主菜单项的页面中使用此额外项应该很有用。

答案 2 :(得分:1)

如果没有current-menu-item,您将得到$(".current-menu-item a").position()作为undefined。然后控制台中的错误

  

无法读取undefined的属性“左”

因此,您必须像下面这样在current-menu-itemwidth()方法中检查css()是否存在。

var $magicLine = $(".site-nav__line"),
    $currentMenu = $(".current-menu-item"); //added this line

$magicLine
    .width($currentMenu.length ? $currentMenu.width() : 0) //chnaged this line
    .css("left", $currentMenu.length ? $currentMenu.find("a").position().left : 0) //chnaged this line
    .data("origLeft", $magicLine.position().left)
    .data("origWidth", $magicLine.width());

快速更新移动鼠标问题:
要在没有current_menu_item时在行中淡入淡出,您必须在hover事件中进行一些更改。并且对于鼠标快速移动问题,您可以使用setTimeoutclearTimeout

var hoverOut;

$(".site-nav__list li a").hover(function() {
  clearTimeout(hoverOut);

  $el = $(this);
  leftPos = $el.position().left;
  newWidth = $el.parent().width();

  if (!$magicLine.width()) {
    $magicLine.stop().hide().css({
      left: leftPos,
      width: newWidth
    }).fadeIn(400);
  } else {
    $magicLine.stop().animate({
      opacity: 1,
      left: leftPos,
      width: newWidth
    });
  }
}, function() {
  hoverOut = setTimeout(function() {
    if (!$currentMenu.length) {
      $magicLine.fadeOut(400, function() {
        $magicLine.css({
          left: $magicLine.data("origLeft"),
          width: $magicLine.data("origWidth")
        });
      });
    } else {
      $magicLine.stop().animate({
        left: $magicLine.data("origLeft"),
        width: $magicLine.data("origWidth")
      });
    }
  }, 400);
});

更新的笔链接: https://codepen.io/anon/pen/RBZwbZ