Skip to content

Commit

Permalink
Merge pull request #36 from jonaskuske/v1.3.2
Browse files Browse the repository at this point in the history
v1.3.2
  • Loading branch information
jonaskuske authored Apr 12, 2020
2 parents 6b4d8db + 5aa395c commit bc759fa
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 9 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.3.2] - 2020-04-12

### Fixed

- The scroll navigation is now prevented if you call `event.preventDefault()` on the click event (fix #32)
- Polyfill now skips handling click events if the href has a query string that is different from the current one (fix #28)
Previously, a navigation from `/?page=1` to `/?page=2#content` would not work: because the path is the same, the polyfill would intercept the navigation even though the different query params meant that the target was an entirely different page/website

## [1.3.0] - 2019-06-12

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,4 @@ ___

 

© 2019, Jonas Kuske
© 2020, Jonas Kuske
21 changes: 14 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-check

/** @license MIT smoothscroll-anchor-polyfill __VERSION__ (c) 2019 Jonas Kuske */
/** @license MIT smoothscroll-anchor-polyfill __VERSION__ (c) 2020 Jonas Kuske */

var _DEBUG_ = true; // removed during minification

Expand All @@ -18,7 +18,7 @@ var _DEBUG_ = true; // removed during minification
/**
* Add flag to Window interface, workaround for type check
* @typedef {{__forceSmoothscrollAnchorPolyfill__: [boolean]}} GlobalFlag @deprecated
* @typedef {Window & GlobalFlag} WindowWithFlag
* @typedef {typeof globalThis & Window & GlobalFlag} WindowWithFlag
* @type {WindowWithFlag} */
var w = (window), d = document, docEl = d.documentElement, dummy = d.createElement('a');
}
Expand Down Expand Up @@ -152,15 +152,21 @@ var _DEBUG_ = true; // removed during minification
* @returns {boolean}
*/
function isAnchorToLocalElement(el) {
// Check if element is an anchor with a fragment in the url
// False if element isn't "a" or href has no #fragment
if (!/^a$/i.test(el.tagName) || !/#/.test(el.href)) return false;

// Fix bug in IE9 where anchor.pathname misses leading slash
var anchorPath = el.pathname;
if (anchorPath[0] !== '/') anchorPath = '/' + anchorPath;

// Check if anchor targets an element on the current page
return (el.hostname === location.hostname && anchorPath === location.pathname);
// False if target isn't current page
if (el.hostname !== location.hostname || anchorPath !== location.pathname) return false;

// False if anchor targets a ?query that is different from the current one
// e.g. /?page=1 → /?page=2#content
if (el.search && el.search !== location.search) return false;

return true;
}

/**
Expand Down Expand Up @@ -260,8 +266,9 @@ var _DEBUG_ = true; // removed during minification
* @param {MouseEvent} evt
*/
function handleClick(evt) {
// Abort if shift/ctrl-click or not primary click (button !== 0)
if (evt.metaKey || evt.ctrlKey || evt.shiftKey || evt.button !== 0) return;
var notPrimaryClick = evt.metaKey || evt.ctrlKey || evt.shiftKey || evt.button !== 0;
if (evt.defaultPrevented || notPrimaryClick) return;

// scroll-behavior not set to smooth? Bail out, let browser handle it
if (!shouldSmoothscroll()) return;

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "smoothscroll-anchor-polyfill",
"version": "1.3.1",
"version": "1.3.2",
"description": "Apply smooth scroll to anchor links to replicate CSS scroll-behavior",
"main": "dist/index.js",
"unpkg": "dist/index.min.js",
Expand Down
35 changes: 35 additions & 0 deletions test/browser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,28 @@ describe('Scroll targeting', () => {
expect(spy).toHaveBeenCalled()
expect(windowSpy).not.toHaveBeenCalled()
})

it('Bails out if anchor targets a URL with different query param', () => {
history.pushState(null, '', '?a')
document.documentElement.setAttribute('style', 'scroll-behavior:smooth');

const noQuery = insertElement('a', { href: '#top' });
const sameQuery = insertElement('a', { href: '?a#top' });
const diffQuery = insertElement('a', { href: '?b#top' });

const spy = jest.spyOn(window, 'scroll');
polyfill();

// works if anchor target has no query at all
noQuery.click();
expect(spy).toHaveBeenCalledTimes(1);
// works if anchor target has same query as current one
sameQuery.click();
expect(spy).toHaveBeenCalledTimes(2);
// bails out if query is different from current one
diffQuery.click()
expect(spy).toHaveBeenCalledTimes(2)
})
})

describe('Ways to enable/disable', () => {
Expand Down Expand Up @@ -290,4 +312,17 @@ describe('Toggling during runtime', () => {
anchor.click()
expect(spy).toHaveBeenCalledTimes(1)
})

it('Allows aborting navigation using evt.preventDefault()', () => {
document.documentElement.setAttribute('style', 'scroll-behavior:smooth')
const anchor = insertElement('a', { href: '#top' })

const spy = jest.spyOn(window, 'scroll')
polyfill()

anchor.addEventListener('click', evt => evt.preventDefault())
anchor.click()

expect(spy).not.toHaveBeenCalled()
})
})

0 comments on commit bc759fa

Please sign in to comment.