Browser Zoom Issues ..... workaround
Posted: Fri Aug 08, 2025 7:01 pm
Hello All,
The browser got a big boost but it still has several bugs associated with zoom functions.
I've worked out a workaround for these issues an want to share them in case someone else comes across this and needs to gain control of the zoom.
The following code does these things:
1. intercepts ctrl mousewheel zoom gestures and blocks keyboard hotkeys
2. shows a panel; with a zoom slider
3. the ctrl+mousewheel is used to drive the slider
4. hides after 1 second
The browser got a big boost but it still has several bugs associated with zoom functions.
I've worked out a workaround for these issues an want to share them in case someone else comes across this and needs to gain control of the zoom.
The following code does these things:
1. intercepts ctrl mousewheel zoom gestures and blocks keyboard hotkeys
2. shows a panel; with a zoom slider
3. the ctrl+mousewheel is used to drive the slider
4. hides after 1 second
Code: Select all
on BrowserBro_InterceptZoomAndPanel pBrowser
// BLOCK CTRL/CMD+WHEEL + KEYBOARD ZOOM; SHOW PANEL; WHEEL DRIVES SLIDER; AUTO-HIDE AFTER 1s
local tScript, tError
put "(function(){" into tScript
put lf & " var d = document;" after tScript
put lf & " var hideTimer = null;" after tScript
// SHOW PANEL & RESET AUTO-HIDE TIMER
put lf & " function showPanelWithAutoHide() {" after tScript
put lf & " var refs = ensurePanel();" after tScript
put lf & " refs.panel.style.display = 'flex';" after tScript
put lf & " if (hideTimer) clearTimeout(hideTimer);" after tScript
put lf & " hideTimer = setTimeout(function(){ refs.panel.style.display = 'none'; }, 1000);" after tScript
put lf & " return refs;" after tScript
put lf & " }" after tScript
// ENSURE PANEL EXISTS; RETURN {panel, slider}
put lf & " function ensurePanel() {" after tScript
put lf & " var panel = d.getElementById('bbZoomPanel');" after tScript
put lf & " var currentZoom = parseFloat(d.body.style.zoom || 1) || 1;" after tScript
put lf & " if (!panel) {" after tScript
put lf & " panel = d.createElement('div');" after tScript
put lf & " panel.id = 'bbZoomPanel';" after tScript
put lf & " panel.style.position = 'fixed';" after tScript
put lf & " panel.style.top = '10px';" after tScript
put lf & " panel.style.left = '5vw';" after tScript
put lf & " panel.style.width = '90vw';" after tScript
put lf & " panel.style.padding = '10px 14px';" after tScript
put lf & " panel.style.backgroundColor = 'rgba(0,0,0,0.5)';" after tScript
put lf & " panel.style.color = '#fff';" after tScript
put lf & " panel.style.borderRadius = '10px';" after tScript
put lf & " panel.style.fontFamily = 'system-ui, -apple-system, Segoe UI, Roboto, sans-serif';" after tScript
put lf & " panel.style.display = 'flex';" after tScript
put lf & " panel.style.alignItems = 'center';" after tScript
put lf & " panel.style.gap = '10px';" after tScript
put lf & " panel.style.boxSizing = 'border-box';" after tScript
put lf & " panel.style.zIndex = '2147483647';" after tScript
put lf & " panel.style.backdropFilter = 'blur(2px)';" after tScript
put lf & " panel.style.pointerEvents = 'auto';" after tScript
put lf & " var label = d.createElement('span');" after tScript
put lf & " label.id = 'bbZoomLabel';" after tScript
put lf & " label.textContent = 'Zoom:';" after tScript
put lf & " label.style.whiteSpace = 'nowrap';" after tScript
put lf & " label.style.fontWeight = '600';" after tScript
put lf & " var slider = d.createElement('input');" after tScript
put lf & " slider.id = 'bbZoomSlider';" after tScript
put lf & " slider.type = 'range';" after tScript
put lf & " slider.min = 0.1;" after tScript
put lf & " slider.max = 5.0;" after tScript
put lf & " slider.step = 0.1;" after tScript
put lf & " slider.value = currentZoom;" after tScript
put lf & " slider.style.flex = '1 1 auto';" after tScript
put lf & " slider.style.width = '100%';" after tScript
put lf & " var pct = d.createElement('span');" after tScript
put lf & " pct.id = 'bbZoomPct';" after tScript
put lf & " pct.textContent = Math.round(currentZoom * 100) + '%';" after tScript
put lf & " pct.style.whiteSpace = 'nowrap';" after tScript
put lf & " pct.style.minWidth = '48px';" after tScript
put lf & " pct.style.textAlign = 'right';" after tScript
put lf & " var eat = function(e){ e.stopPropagation(); };" after tScript
put lf & " ['mousedown','mouseup','click','dblclick','touchstart','touchmove','touchend','pointerdown','pointerup'].forEach(function(ev){" after tScript
put lf & " panel.addEventListener(ev, eat, true);" after tScript
put lf & " });" after tScript
put lf & " slider.oninput = function() {" after tScript
put lf & " var v = parseFloat(this.value) || 1;" after tScript
put lf & " d.body.style.zoom = v;" after tScript
put lf & " panel.style.zoom = (1 / v);" after tScript
put lf & " pct.textContent = Math.round(v * 100) + '%';" after tScript
put lf & " };" after tScript
put lf & " panel.appendChild(label);" after tScript
put lf & " panel.appendChild(slider);" after tScript
put lf & " panel.appendChild(pct);" after tScript
put lf & " d.body.appendChild(panel);" after tScript
put lf & " }" after tScript
put lf & " panel.style.zoom = (1 / (parseFloat(d.body.style.zoom || 1) || 1));" after tScript
put lf & " var s = d.getElementById('bbZoomSlider'); if (s) { s.dispatchEvent(new Event('input')); }" after tScript
put lf & " return { panel: panel, slider: d.getElementById('bbZoomSlider') };" after tScript
put lf & " }" after tScript
put lf & " function adjustZoomBy(steps) {" after tScript
put lf & " var refs = showPanelWithAutoHide();" after tScript
put lf & " var s = refs.slider;" after tScript
put lf & " if (!s) return;" after tScript
put lf & " var min = parseFloat(s.min)||0.1, max = parseFloat(s.max)||5.0, step = parseFloat(s.step)||0.1;" after tScript
put lf & " var v = parseFloat(s.value)||1;" after tScript
put lf & " v = v + steps*step;" after tScript
put lf & " if (v < min) v = min; if (v > max) v = max;" after tScript
put lf & " s.value = (Math.round(v/step)*step).toFixed(2);" after tScript
put lf & " s.dispatchEvent(new Event('input'));" after tScript
put lf & " }" after tScript
put lf & " d.addEventListener('wheel', function(e) {" after tScript
put lf & " if (e.ctrlKey || e.metaKey) {" after tScript
put lf & " e.preventDefault(); e.stopPropagation();" after tScript
put lf & " adjustZoomBy((e.deltaY > 0) ? -1 : 1);" after tScript
put lf & " }" after tScript
put lf & " }, { passive:false, capture:true });" after tScript
put lf & " d.addEventListener('wheel', function(e) {" after tScript
put lf & " var p = e.target && e.target.closest && e.target.closest('#bbZoomPanel');" after tScript
put lf & " if (p) {" after tScript
put lf & " e.preventDefault(); e.stopPropagation();" after tScript
put lf & " adjustZoomBy((e.deltaY > 0) ? -1 : 1);" after tScript
put lf & " }" after tScript
put lf & " }, { passive:false, capture:true });" after tScript
put lf & " d.addEventListener('keydown', function(e){" after tScript
put lf & " if (!(e.ctrlKey || e.metaKey)) return;" after tScript
put lf & " if (e.key === '+' || e.key === '=') { e.preventDefault(); e.stopPropagation(); adjustZoomBy(1); }" after tScript
put lf & " else if (e.key === '-' || e.key === '_') { e.preventDefault(); e.stopPropagation(); adjustZoomBy(-1); }" after tScript
put lf & " else if (e.key === '0') { e.preventDefault(); e.stopPropagation(); var refs = showPanelWithAutoHide(); if (refs.slider){ refs.slider.value = 1; refs.slider.dispatchEvent(new Event('input')); } }" after tScript
put lf & " }, true);" after tScript
put lf & "})();" after tScript
try
if pBrowser = empty then
do wrapInTry(tScript) in widget "JS Engine" of stack "AppStarterStack"
else
do wrapInTry(tScript) in widget ("Instance " & pBrowser) of group "Browsers" of this card of stack "AppStarterStack"
end if
catch tError
put "JavaScript Error: " & tError
end try
end BrowserBro_InterceptZoomAndPanel