Created
September 18, 2025 10:23
-
-
Save justusbluemer/274d52f637556046417116a2f9e820fe to your computer and use it in GitHub Desktop.
Shadow DOM Clicktracking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| document.addEventListener('click', function(e) { | |
| let text = ''; | |
| const MAX_TRAVERSAL_DEPTH = 10; // Prevent infinite traversal | |
| const visited = new Set(); // Prevent cycles | |
| // First, try standard text extraction on the clicked element | |
| text = e.target.innerText || e.target.textContent || e.target.value || ''; | |
| // If no meaningful text, check common data attributes on clicked element | |
| if (!text || text.trim() === '') { | |
| const dataAttrs = ['data-user-need-tag', 'data-text', 'data-label', 'title', 'alt', 'aria-label']; | |
| for (const attr of dataAttrs) { | |
| const attrValue = e.target.getAttribute(attr); | |
| if (attrValue) { | |
| text = attrValue; | |
| break; | |
| } | |
| } | |
| } | |
| // If still no text, do limited traversal up the DOM | |
| if (!text || text.trim() === '') { | |
| let element = e.target; | |
| let depth = 0; | |
| while (element && depth < MAX_TRAVERSAL_DEPTH && !visited.has(element)) { | |
| visited.add(element); | |
| // Check for shadow root (but limit the text to extract) | |
| if (element.shadowRoot) { | |
| const shadowText = element.shadowRoot.textContent || ''; | |
| if (shadowText.trim() && shadowText.length < 200) { // Avoid huge text blocks | |
| text = shadowText; | |
| break; | |
| } | |
| } | |
| // Quick check for data attributes | |
| const quickAttrs = ['data-user-need-tag', 'data-text', 'title']; | |
| for (const attr of quickAttrs) { | |
| const attrValue = element.getAttribute(attr); | |
| if (attrValue && attrValue.length < 100) { // Reasonable length | |
| text = attrValue; | |
| break; | |
| } | |
| } | |
| if (text) break; | |
| // Move up, handling both regular DOM and shadow DOM | |
| element = element.parentElement || element.host; | |
| depth++; | |
| } | |
| } | |
| const clickedElementText = text.trim(); | |
| if (clickedElementText) { | |
| dataLayer.push({ | |
| event: "click", | |
| click_text: clickedElementText | |
| }); | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment