admin管理员组文章数量:1331388
Safari for desktop automatically scrolls the page to any input element that I focus from javascript. This behavior can be seen right here:
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?
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?
Share Improve this question asked Oct 4, 2018 at 17:33 BeowulfenatorBeowulfenator 2,30017 silver badges26 bronze badges3 Answers
Reset to default 3After 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.
I just had the same bug and was able to get my version working with:
setTimeout(function() {
window.scrollTo(x, y);
}, 0);
I think maybe that in Safari 12 (for some reason) the focus method in the HTMLElement Web API takes longer to run than the scrollTo method in the Window Web API. If this is the case, then there ends up being a race condition between the pletion of the focus method and the scrollTo method, resulting in the scroll position staying at the focused element.
Using setTimeout with a delay of 0ms essentially just says "Run this once everything in the call stack is done executing," which seems to fix the issue for me.
Here's a video I used as a resource when debugging: https://www.youtube./watch?v=8aGhZQkoFbQ
Hope this helps!
you can use the preventScroll options to do this.
current?.focus({
preventScroll: true,
});
本文标签:
版权声明:本文标题:javascript - Prevent Safari from automatically scrolling to focused element (scrollback technique stopped working in Safari 12) 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742269352a2444011.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论