Skip to content
DnsLister Forum

Where domain hunters compare notes

JS for Autoscrolling to the selected control

Team,

Something always annoying when I need to scroll to the active control. then a light blub 💡. I have tamper monkey on my browser then I had AI help me with code to scroll to the selected control. it struggled a bit but I was able to guide it through iframes and active selection CSS 😂

Please make sure your match values fits your domain. GCC vs COM or DOD or International.

License: MIT

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ==UserScript== // @name Power Apps: Auto-Scroll to Selected Control v16 // @namespace http://tampermonkey.net/ // @version 16.0 // @description Automatically and seamlessly centers the Tree View on the selected control. // @match IBSURE :) // @match *://*.powerapps.com/* // @match *://*.powerapps.us/* // @match *://*.gov.island.powerapps.us/* // @match *://*/*embed/* // @icon https://www.google.com/s2/favicons?sz=64&domain=powerapps.com // u/grant none // ==/UserScript== (function() { 'use strict'; let isInitialized = false; let lastSelectedNode = null; let scrollTimeout = null; // 1. Core initialization - Waits for the Gov Cloud iframe to load the Tree function tryInitialize() { if (isInitialized) return; const treeContainer = document.querySelector('div[role="tree"]'); if (!treeContainer) return; isInitialized = true; console.log("Tampermonkey: Power Apps Auto-Scroll Initialized."); // Listen for mouse clicks anywhere in the app window.addEventListener('mouseup', function(e) { // Check if the user clicked directly inside the Tree View // If they did, we don't want the screen to jump unexpectedly. const isTreeClick = e.target.closest('div[role="tree"]') !== null; scheduleAutoScroll(!isTreeClick); }, true); // Listen for keyboard navigation (arrows/tab selection) window.addEventListener('keyup', function() { scheduleAutoScroll(true); }, true); } // 2. Resolve the active Fluent UI theme color for selections function getSelectedThemeColor(container) { const dummy = document.createElement('div'); dummy.style.backgroundColor = 'var(--colorNeutralBackground2Selected)'; container.appendChild(dummy); const computedColor = window.getComputedStyle(dummy).backgroundColor; dummy.remove(); return computedColor; } // 3. Debounce the scroll to let React update the DOM first function scheduleAutoScroll(shouldScroll) { clearTimeout(scrollTimeout); // Wait 400ms for Power Apps to apply the CSS classes before we search scrollTimeout = setTimeout(() => executeScrollCheck(shouldScroll), 400); } // 4. The main silent check function executeScrollCheck(shouldScroll) { const treeContainer = document.querySelector('div[role="tree"]'); if (!treeContainer) return; const targetColor = getSelectedThemeColor(treeContainer); if (!targetColor || targetColor === 'rgba(0, 0, 0, 0)' || targetColor === 'transparent') return; let currentSelectedNode = null; // Find the newly selected div const allDivs = treeContainer.querySelectorAll('div'); for (const div of allDivs) { const rect = div.getBoundingClientRect(); if (rect.width === 0 || rect.height === 0) continue; // Skip hidden elements const bg = window.getComputedStyle(div).backgroundColor; if (bg === targetColor) { currentSelectedNode = div.closest('div[role="treeitem"]') || div; break; } } // If we found a selection AND it is different from the last time we checked if (currentSelectedNode && currentSelectedNode !== lastSelectedNode) { lastSelectedNode = currentSelectedNode; // Update tracking so we don't scroll twice // Only execute the physical scroll if the user interacted with the canvas if (shouldScroll) { // Try native browser smooth scroll currentSelectedNode.scrollIntoView({ behavior: 'smooth', block: 'center' }); // Manual scroll math (Fallback for when Microsoft's CSS locks native scrolling) let currentParent = currentSelectedNode.parentElement; while (currentParent && currentParent !== document.body) { const style = window.getComputedStyle(currentParent); if (['auto', 'scroll', 'overlay'].includes(style.overflowY) && currentParent.scrollHeight > currentParent.clientHeight) { const nodeRect = currentSelectedNode.getBoundingClientRect(); const parentRect = currentParent.getBoundingClientRect(); // Center the item exactly in the middle of the scrollable container if (nodeRect.top < parentRect.top || nodeRect.bottom > parentRect.bottom) { const offset = (nodeRect.top - parentRect.top) - (parentRect.height / 2) + (nodeRect.height / 2); currentParent.scrollBy({ top: offset, behavior: 'smooth' }); } break; } currentParent = currentParent.parentElement; } } } } // Check for the iframe every 2 seconds until it finds the Tree View const findIframeInterval = setInterval(() => { tryInitialize(); if (isInitialized) clearInterval(findIframeInterval); }, 2000); })(); 

Source: r/PowerApps · by /u/Chemical-Roll-2064

Leave a Reply

Your email address will not be published. Required fields are marked *