Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 79e9692

Browse files
authoredMay 30, 2020
Extension for trackEvents() using an MutationObserver. (#167)
Added MutationObserver to MatomoTracker Added dynamically adding buttons to example (test MutationObserver) Exposed trackEvents function to useMatomo
1 parent 8740384 commit 79e9692

File tree

5 files changed

+75
-6
lines changed

5 files changed

+75
-6
lines changed
 

‎packages/js/bundle.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/js/example/index.html

+24
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@
2727
Track me!
2828
</button>
2929

30+
</br>
31+
32+
<button
33+
onclick="addDynamicButton()"
34+
>
35+
Add dynamic button
36+
</button>
37+
<div id="buttonContainer"></div>
38+
3039
<script src="../bundle.min.js"></script>
3140
<script>
3241
const MatomoInstance = new window.MatomoTracker.default({
@@ -35,6 +44,21 @@
3544
})
3645

3746
MatomoInstance.trackEvents()
47+
48+
var buttonNum = 0
49+
function addDynamicButton(data) {
50+
buttonNum += 1
51+
var button = document.createElement("button");
52+
button.setAttribute("data-matomo-event", "click")
53+
button.setAttribute("data-matomo-category", "sample-page")
54+
button.setAttribute("data-matomo-action", "click-event")
55+
button.setAttribute("data-matomo-name", "testDynamicButton")
56+
button.setAttribute("data-matomo-value", buttonNum)
57+
button.innerHTML = `Track Event ${buttonNum}`;
58+
59+
var buttonContainer = document.getElementById("buttonContainer");
60+
buttonContainer.appendChild(button);
61+
}
3862
</script>
3963
</body>
4064
</html>

‎packages/js/src/MatomoTracker.ts

+46-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
} from './types'
1414

1515
class MatomoTracker {
16+
mutationObserver?: MutationObserver
17+
1618
constructor(userOptions: UserOptions) {
1719
const options = { ...defaultOptions, ...userOptions }
1820
if (!options.urlBase) {
@@ -78,11 +80,7 @@ class MatomoTracker {
7880
window._paq.push(['enableLinkTracking', active])
7981
}
8082

81-
// Tracks events based on data attributes
82-
trackEvents() {
83-
const elements = Array.from(
84-
document.querySelectorAll<HTMLElement>('[data-matomo-event="click"]'),
85-
)
83+
private trackEventsForElements(elements: HTMLElement[]) {
8684
if (elements.length) {
8785
elements.forEach((element) => {
8886
element.addEventListener('click', () => {
@@ -109,6 +107,49 @@ class MatomoTracker {
109107
}
110108
}
111109

110+
// Tracks events based on data attributes
111+
trackEvents() {
112+
const matchString = '[data-matomo-event="click"]'
113+
let firstTime = false
114+
if (!this.mutationObserver) {
115+
firstTime = true
116+
this.mutationObserver = new MutationObserver((mutations) => {
117+
for (const mutation of mutations) {
118+
// Iterate over NodeList by indices (es15 does not allow using 'let node of mutation.addedNodes')
119+
mutation.addedNodes.forEach((node) => {
120+
// only track HTML elements
121+
if (!(node instanceof HTMLElement)) return
122+
123+
// check the inserted element for being a code snippet
124+
if (node.matches(matchString)) {
125+
this.trackEventsForElements([node])
126+
}
127+
128+
const elements = Array.from(
129+
node.querySelectorAll<HTMLElement>(matchString),
130+
)
131+
this.trackEventsForElements(elements)
132+
})
133+
}
134+
})
135+
}
136+
this.mutationObserver.observe(document, { childList: true, subtree: true })
137+
138+
// Now track all already existing elements
139+
if (firstTime) {
140+
const elements = Array.from(
141+
document.querySelectorAll<HTMLElement>(matchString),
142+
)
143+
this.trackEventsForElements(elements)
144+
}
145+
}
146+
147+
stopObserving() {
148+
if (this.mutationObserver) {
149+
this.mutationObserver.disconnect()
150+
}
151+
}
152+
112153
// Tracks events
113154
// https://matomo.org/docs/event-tracking/#tracking-events
114155
trackEvent({

‎packages/react/src/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { types } from '@datapunt/matomo-tracker-js'
22

33
export interface MatomoInstance {
44
trackEvent?: Function
5+
trackEvents?: Function
56
trackPageView?: Function
67
trackSiteSearch?: Function
78
trackLink?: Function

‎packages/react/src/useMatomo.ts

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ function useMatomo() {
1818
const trackEvent = (params: TrackEventParams) =>
1919
instance.trackEvent && instance.trackEvent(params)
2020

21+
const trackEvents = () => instance.trackEvents && instance.trackEvents()
22+
2123
const trackSiteSearch = (params: TrackSiteSearchParams) =>
2224
instance.trackSiteSearch && instance.trackSiteSearch(params)
2325

@@ -28,6 +30,7 @@ function useMatomo() {
2830

2931
return {
3032
trackEvent,
33+
trackEvents,
3134
trackPageView,
3235
trackSiteSearch,
3336
trackLink,

0 commit comments

Comments
 (0)
This repository has been archived.