From a879b5b5fda434e7581fd3efa4515caab45abf7b Mon Sep 17 00:00:00 2001 From: Wu Cheng-Han Date: Fri, 25 Sep 2015 18:29:01 +0800 Subject: [PATCH] Fixed scrollSpy might not set properly on updateView or windowResize --- public/js/index.js | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/public/js/index.js b/public/js/index.js index 16857d0de..b3fc372f4 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -470,7 +470,8 @@ function windowResizeInner() { clearMap(); syncScrollToView(); editor.setOption('viewportMargin', viewportMargin); - }, windowResizeDelay); + updateScrollspy(); + }, 100); } } @@ -803,6 +804,32 @@ function generateScrollspy() { ui.area.view.scroll(); } +function updateScrollspy() { + var headers = ui.area.markdown.find('h1, h2, h3').toArray(); + var headerMap = []; + for (var i = 0; i < headers.length; i++) { + headerMap.push($(headers[i]).offset().top - parseInt($(headers[i]).css('margin-top'))); + } + applyScrollspyActive($(window).scrollTop(), headerMap, headers, + $('.scrollspy-body'), 0); + var offset = ui.area.view.scrollTop() - ui.area.view.offset().top; + applyScrollspyActive(ui.area.view.scrollTop(), headerMap, headers, + $('.scrollspy-view'), offset - 10); +} + +function applyScrollspyActive(top, headerMap, headers, target, offset) { + var index = 0; + for(var i = headerMap.length - 1; i >= 0; i--) { + if(top >= (headerMap[i] + offset) && headerMap[i + 1] && top < (headerMap[i + 1] + offset)) { + index = i; + break; + } + } + var header = $(headers[index]); + var active = target.find('a[href="#' + header.attr('id') + '"]'); + active.closest('li').addClass('active').parent().closest('li').addClass('active').parent().closest('li').addClass('active'); +} + //fix for wrong autofocus $('#clipboardModal').on('shown.bs.modal', function () { $('#clipboardModal').blur(); @@ -1736,6 +1763,7 @@ function updateViewInner() { generateToc('toc'); generateToc('toc-affix'); generateScrollspy(); + updateScrollspy(); smoothHashScroll(); isDirty = false; clearMap();