单击后,由于平滑滚动jQuery,无法切换W3Schools菜单

时间:2019-04-05 08:05:29

标签: javascript jquery html menu

对于一个简单的网站,我遵循W3Schools tutorial的介绍如何创建响应式汉堡菜单。要关闭它,我发现此simple solution发布在堆栈溢出中。

var topNav = document.querySelector('#myTopnav');
topNav.addEventListener('click', function(e) {
  if (e.target.tagName === 'A') {
    topNav.classList.remove('responsive');
  }
});

但是它似乎对我不起作用。 我什至更改了网站,以适应威胁中显示的示例的完全相同的结构。

现在我发现,一旦删除jQuery代码以平滑滚动,它就可以正常工作。

$(document).ready(function() {
  $('nav a[href*=\\#]').bind('click', function(s) {
    s.preventDefault(); 
    var target = $(this).attr("href"); 

    $('html, body').stop().animate({
      scrollTop: ( $(target).offset().top - 50 ) 
    }, 600, function() {
      location.hash = target;
    });

    return false;
  });
});

有什么主意我可以让它们彼此相邻工作吗?

1 个答案:

答案 0 :(得分:1)

@ bradbury9 在对您的问题的评论中指出,取出s.preventDefault()确实可以解决问题。请查看以下代码段:

function myFunction() {
  var x = document.getElementById("myTopnav");
  if (x.className === "topnav") {
    x.className += " responsive";
  } else {
    x.className = "topnav";
  }
}

// var topNav = document.querySelector('#myTopnav');
// topNav.addEventListener('click', function(e) {
//   if (e.target.tagName === 'A') {
//     topNav.classList.remove('responsive');
//   }
// });


// PAY ATTENTION! I changed the selector from nav to div.topnav!
// This is only because the HTML in the snippet is structured this way!
$('div.topnav a[href*=\\#]').on('click', function(s) {

  s.preventDefault();

  // EDIT: added line to "merge" the two functions,
  // so they don't block each other
  $("#myTopnav").removeClass("responsive");

  var target = $(this).attr("href");

  $('html, body').stop().animate({
    scrollTop: ($(target).offset().top - 50)
  }, 1000, function() {
    location.hash = target;
  });

  // return false;
});
body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}

.topnav {
  overflow: hidden;
  background-color: #333;
}

.topnav a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
}

.topnav a:hover {
  background-color: #ddd;
  color: black;
}

.active {
  background-color: #4CAF50;
  color: white;
}

.topnav .icon {
  display: none;
}

@media screen and (max-width: 600px) {
  .topnav a:not(:first-child) {
    display: none;
  }
  .topnav a.icon {
    float: right;
    display: block;
  }
}

@media screen and (max-width: 600px) {
  .topnav.responsive {
    position: relative;
  }
  .topnav.responsive .icon {
    position: absolute;
    right: 0;
    top: 0;
  }
  .topnav.responsive a {
    float: none;
    display: block;
    text-align: left;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />

<div class="topnav" id="myTopnav">
  <a href="#home" class="active">Home</a>
  <a href="#news">News</a>
  <a href="#contact">Contact</a>
  <a href="#about">About</a>
  <a href="javascript:void(0);" class="icon" onclick="myFunction()">
    <i class="fa fa-bars"></i>
  </a>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div id="news" style="padding-left:16px">
  <h2>Responsive Topnav Example: news</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div id="contact" style="padding-left:16px">
  <h2>Responsive Topnav Example: contact</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

<div style="padding-left:16px">
  <h2>Responsive Topnav Example</h2>
  <p>Resize the browser window to see how it works.</p>
</div>

在小屏幕上

  • 出现汉堡菜单,
  • 点击打开
  • 如果打开,则在下次单击时关闭
  • 如果您单击菜单项(链接),则菜单将关闭

问题是,您将两个click事件绑定到同一元素,并且需要同时处理冒泡/传播,以同时处理两个事件。 (当然,这会导致链接“将起作用”的问题,因为没有什么阻止它起作用的。)

另一种解决方案可能是您从两个单独的函数中选择一个,因此只需要单击一下即可。

编辑 我编辑了代码段,以显示应如何合并功能,还编辑了第一行,因此这并不是真正的答案。