From bf6ac0583085e8e100614a35feb0ede15d126a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Cs=C3=A1sz=C3=A1r?= Date: Wed, 1 Apr 2020 16:43:51 +0200 Subject: [PATCH] Handle clicks of A tags with child elements --- package.json | 2 +- spec/index.spec.ts | 13 +++++++++++++ src/index.ts | 13 ++++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1598ce2..4375207 100644 --- a/package.json +++ b/package.json @@ -41,5 +41,5 @@ "test": "karma start --single-run", "watch": "karma start" }, - "version": "1.0.4" + "version": "1.0.5" } diff --git a/spec/index.spec.ts b/spec/index.spec.ts index 74a69a9..7d29157 100644 --- a/spec/index.spec.ts +++ b/spec/index.spec.ts @@ -13,6 +13,7 @@ describe("scrollToFragment", function (this: { history: History }) { Other page Same page Hash only + Nested ` ); history.replaceState(null, null, "index.html"); @@ -81,6 +82,18 @@ describe("scrollToFragment", function (this: { history: History }) { }); }); + describe("clicking an element wrapped by a hash link", () => { + beforeEach((done) => { + scrollToFragment({ scrollIntoView: () => window.scrollTo(0, 123) }); + document.getElementById("spanInA").click(); + wait(done); + }); + + it("scrolls, overriding the browser default", () => { + expect(window.scrollY).toBeCloseTo(123, -1); + }); + }); + describe("without a URL hash", () => { beforeEach((done) => { scrollToFragment(); diff --git a/src/index.ts b/src/index.ts index 24d76e6..9c6e674 100644 --- a/src/index.ts +++ b/src/index.ts @@ -63,16 +63,19 @@ function handleHistoryPush( } function handleDocumentClick(event: Event) { - if ((event.target as Node).nodeName !== "A") return; - - const anchor = event.target as HTMLAnchorElement; - if (anchor.href.indexOf("#") === -1) return; - + const anchor = closestAIncludingSelf(event.target as HTMLElement); + if (!anchor || anchor.href.indexOf("#") === -1) return; if (anchor.href.replace(/#.*/, "") === location.href.replace(/#.*/, "")) { throttle(startObserving); } } +function closestAIncludingSelf(element?: HTMLElement) { + let target = element; + while (target && target.nodeName !== "A") target = target.parentElement; + return target as HTMLAnchorElement | void; +} + function handleDomMutation() { throttle(adjustScrollPosition); }