scroll-to-text-fragment-target.html (3470B)
1 <!doctype html> 2 <title>Navigating to a text fragment anchor</title> 3 <script src="stash.js"></script> 4 <meta name="viewport" content="width=device-width,initial-scale=1"> 5 <script> 6 function isInView(element) { 7 let rect = element.getBoundingClientRect(); 8 return rect.top >= 0 && rect.top <= window.innerHeight 9 && rect.left >= 0 && rect.left <= window.innerWidth; 10 } 11 12 function checkScroll() { 13 let position = 'unknown'; 14 if (window.scrollY == 0) 15 position = 'top'; 16 else if (isInView(document.getElementById('element'))) 17 position = 'element'; 18 else if (isInView(document.getElementById('text'))) 19 position = 'text'; 20 else if (isInView(document.getElementById('more-text'))) 21 position = 'more-text'; 22 else if (isInView(document.getElementById('cross-node-context'))) 23 position = 'cross-node-context'; 24 else if (isInView(document.getElementById('text-directive-parameters'))) 25 position = 'text-directive-parameters'; 26 else if (isInView(document.getElementById('shadow-parent'))) 27 position = 'shadow-parent'; 28 else if (isInView(document.getElementById('hidden'))) 29 position = 'hidden'; 30 else if (isInView(document.getElementById('horizontal-scroll')) && window.scrollX > 0) 31 position = 'horizontal-scroll'; 32 33 let target = document.querySelector(":target"); 34 35 if (!target && position == 'shadow-parent') { 36 let shadow = document.getElementById("shadow-parent").shadowRoot.firstElementChild; 37 if (shadow.matches(":target")) { 38 target = shadow; 39 position = 'shadow'; 40 } 41 } 42 43 let results = { 44 scrollPosition: position, 45 href: window.location.href, 46 performanceNavigationEntries: performance.getEntriesByType("navigation").map(e => e.name), 47 performanceResourcesEntries: performance.getEntriesByType("resource").map(e => e.name), 48 target: target ? target.id : 'undefined' 49 }; 50 51 let key = (new URL(document.location)).searchParams.get("key"); 52 stashResultsThenClose(key, results); 53 } 54 55 // Ensure two animation frames on load to test the fallback to element anchor, 56 // which gets queued for the next frame if the text fragment is not found. 57 window.onload = function() { 58 window.requestAnimationFrame(function() { 59 window.requestAnimationFrame(checkScroll); 60 }) 61 } 62 </script> 63 <style> 64 .scroll-section { 65 /* 100vh margin on top and bottom so only one section can be in view. */ 66 margin: 100vh 0px; 67 } 68 #hidden { 69 visibility: hidden; 70 } 71 #horizontal-scroll { 72 margin-left: 2000px; 73 } 74 #display-none { 75 display: none; 76 } 77 </style> 78 <body> 79 <div id="element" class="scroll-section">Element</div> 80 <p id="text" class="scroll-section"> 81 This is a test page !$'()*+./:;=?@_~ &,- ネコ 82 <br> 83 foo foo foo bar bar bar 84 </p> 85 <p id="more-text" class="scroll-section">More test page text</p> 86 <div class="scroll-section"> 87 <div> 88 <p>prefix</p> 89 <p id="cross-node-context">test page</p> 90 </div> 91 <div><p>suffix</p></div> 92 </div> 93 <p id="text-directive-parameters" class="scroll-section">this,is,test,page</p> 94 <div id="shadow-parent" class="scroll-section"></div> 95 <script> 96 let shadow = document.getElementById("shadow-parent").attachShadow({mode: 'open'}); 97 shadow.innerHTML = '<p id="shadow">shadow text</p>'; 98 </script> 99 <p id="hidden" class="scroll-section">hidden text</p> 100 <p id="horizontal-scroll" class="scroll-section">horizontally scrolled text</p> 101 <p id="display-none" class="scroll-section">display none</p> 102 </body>