点击

时间:2017-09-23 18:03:59

标签: javascript

我正在尝试在我的网站上实现平滑滚动。我有链接,我想用于滚动元素:

<nav id="page-nav" class="nav section-links">
   <button class="active" data-target="#info">Info</button>
   <button data-target="#videos">Videos</button>
   <button data-target="#stats">Statistics</button>
</nav>

我在这样的按钮上附加了click事件监听器:

$(document).ready(function () {
  var navigationLinks = document.getElementsByClassName('section-links')[0].getElementsByTagName('button');
  Array.prototype.forEach.call(navigationLinks, child => {
    console.log(child);
    child.addEventListener('click', doScrolling(child.getAttribute('data-target')));
  });
});

这是doScrolling函数:

function getElementY(query) {
  return window.pageYOffset + document.querySelector(query).getBoundingClientRect().top
}

function doScrolling(element, duration) {
  var duration = duration || 1000;
  var startingY = window.pageYOffset
  var elementY = getElementY(element)

  // If element is close to page's bottom then window will scroll only to some position above the element.
  var targetY = document.body.scrollHeight - elementY < window.innerHeight ? document.body.scrollHeight - window.innerHeight : elementY
  var diff = targetY - startingY
  // Easing function: easeInOutCubic
  // From: https://gist.github.com/gre/1650294
  var easing = function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 }
  var start

  if (!diff) return

    // Bootstrap our animation - it will get called right before next frame shall be rendered.
    window.requestAnimationFrame(function step(timestamp) {
    if (!start) start = timestamp
    // Elapsed miliseconds since start of scrolling.
    var time = timestamp - start
        // Get percent of completion in range [0, 1].
    var percent = Math.min(time / duration, 1)
    // Apply the easing.
    // It can cause bad-looking slow frames in browser performance tool, so be careful.
    percent = easing(percent)

    window.scrollTo(0, startingY + diff * percent)

        // Proceed with animation as long as we wanted it to.
    if (time < duration) {
      window.requestAnimationFrame(step)
    }
  })
}

但是,当我点击按钮时没有任何反应,控制台中没有错误,我不确定发生了什么。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

您实际上在做什么是将doScrolling函数调用的结果作为事件处理程序附加。这就是它没有按预期工作的原因。

您应该将doScrolling调用包装到函数中,并将目标值存储在闭包中。

$(document).ready(function () {
  var navigationLinks = document.getElementsByClassName('section-links')[0].getElementsByTagName('button');
  Array.prototype.forEach.call(navigationLinks, child => {
    var target = child.getAttribute('data-target');
    child.addEventListener('click', function () { doScrolling(target) });
  });
});

function getElementY(query) {
  return window.pageYOffset + document.querySelector(query).getBoundingClientRect().top
}

function doScrolling(element, duration) {
  var duration = duration || 1000;
    var startingY = window.pageYOffset
  var elementY = getElementY(element)

  // If element is close to page's bottom then window will scroll only to some position above the element.
  var targetY = document.body.scrollHeight - elementY < window.innerHeight ? document.body.scrollHeight - window.innerHeight : elementY
    var diff = targetY - startingY
  // Easing function: easeInOutCubic
  // From: https://gist.github.com/gre/1650294
  var easing = function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 }
  var start

  if (!diff) return

    // Bootstrap our animation - it will get called right before next frame shall be rendered.
    window.requestAnimationFrame(function step(timestamp) {
    if (!start) start = timestamp
    // Elapsed miliseconds since start of scrolling.
    var time = timestamp - start
        // Get percent of completion in range [0, 1].
    var percent = Math.min(time / duration, 1)
    // Apply the easing.
    // It can cause bad-looking slow frames in browser performance tool, so be careful.
    percent = easing(percent)

    window.scrollTo(0, startingY + diff * percent)

        // Proceed with animation as long as we wanted it to.
    if (time < duration) {
      window.requestAnimationFrame(step)
    }
  })
}
.content {
  height: 100vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="page-nav" class="nav section-links">
   <button class="active" data-target="#info">Info</button>
   <button data-target="#videos">Videos</button>
   <button data-target="#stats">Statistics</button>
</nav>

<div class="content" id="info">Info</div>
<div class="content" id="videos">Videos</div>
<div class="content" id="stats">Stats</div>

答案 1 :(得分:0)

&#34;点击添加事件监听器无效。&#34;

您的事件监听器没问题,请参阅:

&#13;
&#13;
$(document).ready(function () {
  var navigationLinks = document.getElementsByClassName('section-links')[0].getElementsByTagName('button');
  Array.prototype.forEach.call(navigationLinks, child => {
    console.log(child);
    child.addEventListener('click', function() { console.log("click") });
  });
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="page-nav" class="nav section-links">
   <button class="active" data-target="#info">Info</button>
   <button data-target="#videos">Videos</button>
   <button data-target="#stats">Statistics</button>
</nav>
&#13;
&#13;
&#13;