function debounce (func, wait, immediate) { var timeout; return function () { var context = this, args = arguments; var later = function () { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; function _syncScroll (src, dst) { var ratio = dst.scrollHeight / src.scrollHeight; dst.scrollTop = Math.round(src.scrollTop * ratio); } var syncScroll = debounce(_syncScroll, 5); var one = document.getElementById('one'); var two = document.getElementById('two'); one.addEventListener('scroll', syncScroll.bind(null, one, two)); two.addEventListener('scroll', syncScroll.bind(null, two, one));