使用 SVG 时,ScrollIntoView 在 Firefox 中出现错误
ScrollIntoView bugged in firefox when using SVG
我有一个垂直长的 SVG 图像,我需要滚动到具有特定 id 的特定元素。
const el = document.getElementById(id);
el.scrollIntoView({
behavior: 'smooth',
block: 'center'
});
这在 chrome 中工作正常,但 Firefox 滚动到 SVG 文件的顶部,而不是所选元素。
我在 stackblitz 中重现了这个错误:
https://stackblitz.com/edit/react-wkoiwq
https://react-wkoiwq.stackblitz.io
在 chrome 中,#hotplate 元素移动到中心,而在 Firefox 中,SVG 的顶部移动到中心。
尝试将 center
更改为 start
和 end
以查看效果。
有没有办法解决/避免这个问题?
也许手动执行是正确的解决方案:
el.getBoundingClientRect().top
获取相对于视口的位置。
window.pageYOffset
获取当前视口偏移量。
document.clientHeight
获取视口高度(没有滚动条)
- 计算所需的偏移量(相对于文档元素),并使用
window.scrollTo
滚动。
例如:
var el = document.getElementById("hotplate");
// { block: "top" } behavior:
let newScrollY = window.pageYOffset + el.getBoundingClientRect().top;
// adjust to behave like { block: "center" }
newScrollY = newScrollY - document.documentElement.clientHeight/2;
window.scrollTo({top: newScrollY, behavior: 'smooth'});
我认为主要问题是 Firefox 动画到元素 #hotplate 的原始位置,该元素位于父 SVG 的边界。 Firefox 不考虑 y 属性。
为了克服这个问题,您可以将 svg 代码包装在一个容器中,并添加一个与具有绝对位置的 svg 子元素具有相同位置的跨度。
您可以将 HTML 更改为:
<div class='container'>
<span id='hotplate-ref"></span>
<svg>.....</svg>
</div>
然后添加到您的 CSS:
.container
{
position: relative;
}
#hotplate-ref
{
position: absolute;
top: 1703px; /* includes margin top of svg (1400px) + y attribute of svg element (503px) */
width: 0px;
height: 0px;
visibility: hidden;
pointer-events: none;
}
最后将 "componentDidMount()" 更改为:
const el = document.getElementById("hotplate-ref");
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
我在 Chrome 和 FF 中测试了代码,它工作正常。
显然,您也可以对其他 svg 子元素执行此操作。
我有一个垂直长的 SVG 图像,我需要滚动到具有特定 id 的特定元素。
const el = document.getElementById(id);
el.scrollIntoView({
behavior: 'smooth',
block: 'center'
});
这在 chrome 中工作正常,但 Firefox 滚动到 SVG 文件的顶部,而不是所选元素。
我在 stackblitz 中重现了这个错误:
https://stackblitz.com/edit/react-wkoiwq
https://react-wkoiwq.stackblitz.io
在 chrome 中,#hotplate 元素移动到中心,而在 Firefox 中,SVG 的顶部移动到中心。
尝试将 center
更改为 start
和 end
以查看效果。
有没有办法解决/避免这个问题?
也许手动执行是正确的解决方案:
el.getBoundingClientRect().top
获取相对于视口的位置。window.pageYOffset
获取当前视口偏移量。document.clientHeight
获取视口高度(没有滚动条)- 计算所需的偏移量(相对于文档元素),并使用
window.scrollTo
滚动。
例如:
var el = document.getElementById("hotplate");
// { block: "top" } behavior:
let newScrollY = window.pageYOffset + el.getBoundingClientRect().top;
// adjust to behave like { block: "center" }
newScrollY = newScrollY - document.documentElement.clientHeight/2;
window.scrollTo({top: newScrollY, behavior: 'smooth'});
我认为主要问题是 Firefox 动画到元素 #hotplate 的原始位置,该元素位于父 SVG 的边界。 Firefox 不考虑 y 属性。
为了克服这个问题,您可以将 svg 代码包装在一个容器中,并添加一个与具有绝对位置的 svg 子元素具有相同位置的跨度。
您可以将 HTML 更改为:
<div class='container'>
<span id='hotplate-ref"></span>
<svg>.....</svg>
</div>
然后添加到您的 CSS:
.container
{
position: relative;
}
#hotplate-ref
{
position: absolute;
top: 1703px; /* includes margin top of svg (1400px) + y attribute of svg element (503px) */
width: 0px;
height: 0px;
visibility: hidden;
pointer-events: none;
}
最后将 "componentDidMount()" 更改为:
const el = document.getElementById("hotplate-ref");
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
我在 Chrome 和 FF 中测试了代码,它工作正常。
显然,您也可以对其他 svg 子元素执行此操作。