2017-09-23 79 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