2017-09-23 85 views
1

我试图在我的网站上实现平滑滚动。我有我想要使用滚动元素链接:平滑滚动不起作用点击

<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> 

我上的按钮安装单击事件监听器是这样的:

$(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) 
    } 
    }) 
} 

但是,当我点击按钮时没有任何反应,控制台中没有错误,我不知道发生了什么。我怎样才能解决这个问题?

回答

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>

+0

是的,就是这样,谢谢! – Leff

0

“点击添加事件监听器不起作用。”

事件侦听器是OK,请参阅:

$(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") }); 
 
    }); 
 
});
<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>

+0

我不知道,什么是错的,然后? – Leff