可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a page where a scroll bar containing table rows with divs in them is dynamically generated from the database. Each table row acts like a link, sort of like you'd see on a YouTube playlist next to the video player.
When a user visits the page, the option they are on is supposed to go to the top of the scrolling div. This functionality is working. The issue is that it goes just a tad too far. Like the option they are on is about 10px too high. So, the page is visited, the url is used to identify which option was selected and then scrolls that option to the top of the scrolling div. Note: This is not the scroll bar for the window, it is a div with a scrollbar.
I am using this code to make it move the selected option to the top of the div:
var pathArray = window.location.pathname.split( '/' );
var el = document.getElementById(pathArray[5]);
el.scrollIntoView(true);
It moves it to the top of the div but about 10 pixels too far up.
Anyone know how to fix that?
回答1:
If it's about 10px, then I guess you could simply manually adjust the containing div
's scroll offset like that:
el.scrollIntoView(true);
document.getElementById("containingDiv").scrollTop += 10;
回答2:
You can do it in two steps :
el.scrollIntoView(true);
window.scrollBy(0, -10); // Adjust scrolling with a negative value here
回答3:
Position Anchor By Absolute Method
Another way do do this is to position your anchors exactly where you want on the page rather than relying on scrolling by offset. I find it allows better control for each element (eg. if you want a different offset for certain elements), and may also be more resistant to browser API changes/differences.
<div id="title-element" style="position: relative;">
<div id="anchor-name" style="position: absolute; top: -100px; left: 0" />
</div>
Now the offset is specified as -100px relative to the element. Create a function to create this anchor for code reuse, or if you are using a modern JS framework such as React do this by creating a component that renders your anchor, and pass in the anchor name and alignment for each element, which may or may not be the same.
Then just use :
const element = document.getElementById('anchor-name')
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
For smooth scrolling with an offset of 100px.
回答4:
You can also use the element.scrollIntoView()
options
el.scrollIntoView(
{
behavior: 'smooth',
block: 'start'
},
);
which most browsers support
回答5:
Building on an earlier answer, I am doing this in an Angular5 project.
Started with:
// el.scrollIntoView(true);
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
window.scrollBy(0, -10);
But this gave some problems and needed to setTimeout for the scrollBy() like this:
//window.scrollBy(0,-10);
setTimeout(() => {
window.scrollBy(0,-10)
}, 500);
And it works perfectly in MSIE11 and Chrome 68+. I have not tested in FF. 500ms was the shortest delay I would venture. Going lower sometimes failed as the smooth scroll had not yet completed. Adjust as required for your own project.
+1 to Fred727 for this simple but effective solution.
回答6:
Assuming you want to scroll to the divs that are all at the same level in DOM and have class name "scroll-with-offset", then this CSS will solve the issue:
.scroll-with-offset {
padding-top: 100px;
margin-bottom: -100px;
}
The offset from the top of the page is 100px. It will only work as intended with block: 'start':
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
What's happening is that the divs' top point is at the normal location but their inner contents start 100px below the normal location. That's what padding-top:100px is for. margin-bottom: -100px is to offset the below div's extra margin.
To make the solution complete also add this CSS to offset the margins/paddings for the top-most and bottom-most divs:
.top-div {
padding-top: 0;
}
.bottom-div {
margin-bottom: 0;
}
回答7:
I've got this and it works brilliantly for me:
// add a smooth scroll to element
scroll(el) {
el.scrollIntoView({
behavior: 'smooth',
block: 'start'});
setTimeout(() => {
window.scrollBy(0, -40);
}, 500);}
Hope it helps.
回答8:
This works for me in Chrome (With smooth scrolling and no timing hacks)
It just moves the element, initiates the scroll, then moves it back.
There is no visible "popping" if the element is already on the screen.
pos = targetEle.style.position;
top = targetEle.style.top;
targetEle.style.position = 'relative';
targetEle.style.top = '-20px';
targetEle.scrollIntoView({behavior: 'smooth', block: 'start');
targetEle.style.top = top;
targetEle.style.position = pos;