首页 > 解决方案 > 防止 Safari 自动滚动到焦点元素(回滚技术在 Safari 12 中停止工作)

问题描述

桌面版 Safari 会自动将页面滚动到我从 javascript 关注的任何输入元素。这种行为可以在这里看到:

https://codepen.io/anon/pen/JmKPwZ

我发现没有办法阻止这种自动滚动。但是,有一个已知的解决方法 - 首先保存屏幕位置并在聚焦后滚动回该位置:

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

此解决方法过去在 Safari 10 中运行良好,但在 Safari 12 中停止运行。scrollTo聚焦后调用不再执行任何操作。但是,如果scrollTo延迟执行(即使是很短的延迟),一切正常:

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);

但是有了这个 1 毫秒的延迟,我们可以看到页面首先滚动到输入字段,然后很快又回到原来的位置,所以新的解决方法远非完美。

有什么方法可以优雅地阻止桌面 Safari 自动将页面滚动到焦点元素,或者至少是缓解这种行为的好方法?

标签: javascriptmacossafari

解决方案


经过多次探索,我偶然发现了一个可行的解决方案:

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;

出于某种原因,保存document.body.scrollTop有效,而保存window.scrollXwindow.scrollY无效。


推荐阅读