2017-09-23 6 views
1

Ich versuche, reibungsloses Scrollen auf meiner Website zu implementieren. Ich habe Links, die ich für das Scrollen auf Elemente verwenden möchten:Smooth Scrolling funktioniert nicht auf Klick

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

I Klick-Ereignis-Listener auf Schaltflächen wie diese bin Befestigung:

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

Dies ist die doScrolling Funktion:

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

Aber wenn ich auf Knöpfe klicke passiert nichts, es gibt keine Fehler in der Konsole, und ich bin mir nicht sicher, was vor sich geht. Wie kann ich das beheben?

Antwort

3

Was Sie wirklich tun Sie Ergebnis doScrolling Funktionsaufruf als Event-Handler zu befestigen. Deshalb funktioniert es nicht wie erwartet.

Sie sollten den doScrolling-Aufruf in eine Funktion einschließen und den Zielwert in einem Abschluss speichern.

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

Ja, das war es, danke! – Leff

0

"Bei Klick hinzufügen Ereignis Listener funktioniert nicht."

Ihre Ereignis-Listener in Ordnung ist, siehe:

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

Ich bin nicht sicher, was ist dann falsch? – Leff

Verwandte Themen