Safari for desktop automatically scrolls the page to any input element that I focus from javascript. This behavior can be seen right here:
https://codepen.io/anon/pen/JmKPwZ
I have found no way to prevent this automatic scrolling. However, there is a known workaround - save the screen position first and scroll back to that position after focusing:
var el = document.getElementById("editable");
var x = window.scrollX, y = window.scrollY; // save position
el.focus();
// manipulate selection inside the focused element with `document.createRange()`
// and do other stuff
window.scrollTo(x, y); // restore position
This workaround used to work fine in Safari 10 and stopped working in Safari 12. Calling scrollTo
after focusing doesn't do anything anymore. However, if scrollTo
is executed with a delay (even a really short one), everything works:
var el = document.getElementById("editable");
var x = window.scrollX, y = window.scrollY; // save position
el.focus();
// manipulate selection inside the focused element with `document.createRange()`
// and do other stuff
setTimeout(function() {
window.scrollTo(x, y); // restore position
}, 1);
But with this 1-millisecond delay one can see the page first scrolls to the input field and then very quickly back to the original position, so the new workaround is far from perfect.
Is there any way to gracefully prevent desktop Safari from scrolling the page to focused element automatically or at least a good workaround to mitigate that behavior?
After much poking around I've stumbled upon a solution that works:
var el = document.getElementById("editable");
var scrollTop = document.body.scrollTop; // save position
el.focus();
// manipulate selection inside the focused element with `document.createRange()`
// and do other stuff
document.body.scrollTop = scrollTop;
For some reason saving document.body.scrollTop
works, while saving window.scrollX
and window.scrollY
doesn't.