Element
接口提供了scrollIntoView
方法,用于设置所有祖先元素的滚动位置,以便给定元素在屏幕上可见。
Range
执行类似的操作,也就是说,滚动任何需要滚动的内容,以便该范围在屏幕上可见?
我可能可以忍受手动计算范围的边界框并查找要滚动的元素,但我不希望以任何方式修改 DOM 的内容。
Range
有一个名为 getBoundingClientRect
的有用方法,它返回一个 DOMRect
描述范围相对于视口的位置。然后,您可以使用 window.scrollBy
将元素滚动到视图中。一个非常简单的例子:
document.querySelector("#scroll-demo").addEventListener("click", function() {
let selection = window.getSelection();
if (selection.rangeCount === 0) {
return;
}
let range = window.getSelection().getRangeAt(0);
let rect = range.getBoundingClientRect();
if (rect.top < 0 || rect.bottom > document.documentElement.clientHeight) {
// scroll if some part of selection is above the viewport
// or some part is below the viewport, otherwise dont
window.scrollBy(0, rect.y);
}
});
body {
font: medium sans-serif;
}
p:nth-child(even) {
background-color: #EEE;
}
#demos {
position: fixed;
right: 0;
top: 0;
padding: 1em;
color: #FFF;
background-color: #000A;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc aliquam ultricies quam, non porttitor diam iaculis vitae. Nulla rutrum erat et tortor aliquet bibendum. Ut suscipit sapien id accumsan rutrum. Quisque eleifend tempor dolor sit amet luctus.
Quisque non malesuada tortor. Nam sapien orci, consectetur dignissim magna eget, cursus gravida ligula. Quisque efficitur ornare felis, et venenatis ipsum laoreet vel. Sed nunc risus, imperdiet a porttitor eget, auctor eget neque. Donec tincidunt a
est nec sodales. Suspendisse pellentesque est at luctus interdum. Quisque justo orci, vestibulum eget sapien et, faucibus imperdiet turpis. Etiam vel volutpat orci. Nullam tellus elit, bibendum a nulla quis, porttitor euismod sem.</p>
<p>Fusce vehicula nulla quis iaculis commodo. In in efficitur urna. Quisque sem nisl, luctus id porta ac, pellentesque a tellus. Pellentesque lacinia nisl non neque bibendum accumsan. Praesent vitae facilisis dolor. Sed vel ipsum non mauris consequat aliquet.
Pellentesque tellus purus, consequat ut erat convallis, pretium molestie justo.</p>
<p>Maecenas sit amet laoreet leo, vel consectetur purus. Nunc in rhoncus ex. Etiam ultricies mauris ac felis aliquam semper. Morbi eleifend, justo a tincidunt pellentesque, est erat tincidunt nisi, tincidunt dictum nisi ipsum id nunc. Aliquam vel libero
ipsum. In hac habitasse platea dictumst. Curabitur rhoncus risus in ultricies tempus. Vivamus elementum augue ac elit facilisis interdum. Duis tincidunt eget tortor posuere facilisis. Suspendisse fringilla, purus et faucibus tempus, dui elit viverra
arcu, et iaculis massa justo eget ante. Nunc maximus gravida nulla ac tristique. Etiam vel tellus erat.</p>
<p>Nunc vitae risus dignissim, ultricies turpis at, bibendum erat. Mauris at ullamcorper lorem, eget posuere arcu. Aliquam quis libero turpis. Nullam maximus nisl enim, quis pellentesque lacus efficitur non. Fusce consectetur, erat vel elementum porttitor,
risus libero vulputate risus, at porta ante lorem nec lorem. Sed vitae dolor in nisl tincidunt dapibus. Aliquam id velit sit amet ipsum pulvinar condimentum ut quis massa. Aenean id urna a nunc efficitur pulvinar. Ut sed hendrerit lectus. Sed fringilla
urna eu nibh egestas, ac euismod sem hendrerit. Aliquam et risus accumsan, congue leo sed, ornare lacus. Nunc luctus erat odio, ut ultricies dui efficitur ut.</p>
<p>Praesent dapibus est nulla. Cras posuere, risus vel molestie porttitor, ipsum sapien pretium dolor, vitae bibendum arcu massa eget velit. Nunc laoreet lacinia ligula, vel ullamcorper est suscipit finibus. Sed sagittis ipsum vitae odio faucibus porta.
In hac habitasse platea dictumst. Cras vitae consectetur nisl. Ut id arcu condimentum, auctor erat quis, volutpat ligula. Nulla vitae diam at odio dapibus auctor id sed lectus. Integer ac pharetra nisi, ac tincidunt dolor. Cras nec massa et purus dictum
faucibus eget sed nisi. Phasellus interdum urna nec sem lobortis, non condimentum erat porta. Pellentesque sodales sit amet erat ut vulputate. Sed laoreet quis eros quis mollis. Pellentesque scelerisque mauris ornare interdum commodo. Nunc id rhoncus
purus. Nullam sed enim nec ex dignissim pretium.</p>
<div id="demos">
Select something in the document<br> then scroll it outside the viewport<br>
<button id="scroll-demo">Scroll selection into view</button>
</div>