From: Marius Olbertz Date: Sat, 30 Jul 2016 20:05:47 +0000 (+0200) Subject: Fixed Magellan issue when target does not exist. X-Git-Tag: v6.2.4-rc1~31^2~1^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F9070%2Fhead;p=thirdparty%2Ffoundation%2Ffoundation-sites.git Fixed Magellan issue when target does not exist. Prevent any scrolling action when the target of the clicked link does not exist. Previously the `.getOffset().top` created an JS error because `Cannot read property 'top' of undefined`. Also added a basic test for scrolling and a test for the graceful failing when the target does not exist. --- diff --git a/js/foundation.magellan.js b/js/foundation.magellan.js index 64b264c71..5f50c35db 100644 --- a/js/foundation.magellan.js +++ b/js/foundation.magellan.js @@ -103,6 +103,8 @@ class Magellan { * @function */ scrollToLoc(loc) { + // Do nothing if target does not exist to prevent errors + if (!$(loc).length) {return false;} var scrollPos = Math.round($(loc).offset().top - this.options.threshold / 2 - this.options.barOffset); $('html, body').stop(true).animate({ scrollTop: scrollPos }, this.options.animationDuration, this.options.animationEasing); diff --git a/test/javascript/components/magellan.js b/test/javascript/components/magellan.js index 26678f2c5..23e6d4f5e 100644 --- a/test/javascript/components/magellan.js +++ b/test/javascript/components/magellan.js @@ -1,6 +1,31 @@ describe('Magellan', function() { var plugin; - var $html; + var $html, $content; + + var generateUl = function(count) { + var html = ''; + html += ''; + return html; + }; + var generateContent = function(count) { + var html = ''; + html += '
'; + for (var c = 0; c < count; c++) { + html += '
Section ' + c + '
'; + } + html += '
'; + return html; + }; + + afterEach(function() { + plugin.destroy(); + $html.remove(); + $content.remove(); + }); // afterEach(function() { // plugin.destroy(); @@ -17,4 +42,54 @@ describe('Magellan', function() { // }); }); + + describe('scrollToLoc()', function() { + it('scrolls the selected element into viewport', function(done) { + var count = 5, duration = 200; + $html = $(generateUl(count)).appendTo('body'); + $content = $(generateContent(count)).appendTo('body'); + plugin = new Foundation.Magellan($html, { + animationDuration: duration + }); + + + + // Jump to last section + var target = $html.find('a').eq(-1).attr('href'); + plugin.scrollToLoc(target); + + // The `update` event doesn't work properly because it fires too often + setTimeout(function() { + var isInViewport = false; + if ($content.find('div').eq(-1).offset().top > $('body').scrollTop() && $content.offset().top < $('body').scrollTop() + $('body').innerHeight()) { + isInViewport = true; + } + isInViewport.should.equal(true); + done(); + }, duration); + + }); + + + it('fails gracefully when target does not exist', function() { + var count = 5, duration = 200; + $html = $(generateUl(count)).appendTo('body'); + $content = $(generateContent(count - 1)).appendTo('body'); + plugin = new Foundation.Magellan($html, { + animationDuration: duration + }); + + var hasError = false; + try { + var target = $html.find('a').eq(-1).attr('href'); + plugin.scrollToLoc(target); + } catch (err) { + hasError = true; + } + hasError.should.equal(false); + + }); + + }); + }); \ No newline at end of file