Javascript 滚动查看滚动得太远

Javascript 滚动查看滚动得太远,javascript,dom,scroll,Javascript,Dom,Scroll,我有一个页面,其中一个滚动条包含从数据库动态生成的带有div的表行。每个表格行都像一个链接,有点像视频播放器旁边的YouTube播放列表 当用户访问页面时,他们所使用的选项应该位于滚动div的顶部。此功能正在运行。问题是它有点太过分了。就像他们所选择的那样,大约10像素太高了。因此,访问页面时,url用于确定选择了哪个选项,然后将该选项滚动到滚动div的顶部。注意:这不是窗口的滚动条,而是带有滚动条的div 我正在使用此代码使其将所选选项移动到div的顶部: var pathArray = wi

我有一个页面,其中一个滚动条包含从数据库动态生成的带有div的表行。每个表格行都像一个链接,有点像视频播放器旁边的YouTube播放列表

当用户访问页面时,他们所使用的选项应该位于滚动div的顶部。此功能正在运行。问题是它有点太过分了。就像他们所选择的那样,大约10像素太高了。因此,访问页面时,url用于确定选择了哪个选项,然后将该选项滚动到滚动div的顶部。注意:这不是窗口的滚动条,而是带有滚动条的div

我正在使用此代码使其将所选选项移动到div的顶部:

var pathArray = window.location.pathname.split( '/' );

var el = document.getElementById(pathArray[5]);

el.scrollIntoView(true);
它会将其移动到div的顶部,但是向上移动了大约10个像素。
有人知道如何解决这个问题吗?

如果它大约是10px,那么我想您可以简单地手动调整containing
div
的滚动偏移量,如下所示:

el.scrollIntoView(true);
document.getElementById("containingDiv").scrollTop -= 10;

您可以通过两个步骤完成此操作:

el.scrollIntoView(true);
window.scrollBy(0, -10); // Adjust scrolling with a negative value here

您还可以使用
元素。scrollIntoView()

哪种浏览器

以绝对方式定位锚点 另一种方法是将你的锚定位在你想要的页面位置,而不是依靠按偏移量滚动。我发现它可以更好地控制每个元素(例如,如果您想为某些元素设置不同的偏移量),并且还可以更好地抵抗浏览器API的更改/差异

<div id="title-element" style="position: relative;">
  <div id="anchor-name" style="position: absolute; top: -100px; left: 0"></div>
</div>

为了平滑滚动,偏移量为100px。

基于前面的答案,我在Angular5项目中这样做

首先是:

// el.scrollIntoView(true);
el.scrollIntoView({
   behavior: 'smooth',
   block: 'start'
});
window.scrollBy(0, -10); 
但这会带来一些问题,需要像这样设置scrollBy()的超时:

//window.scrollBy(0,-10);
setTimeout(() => {
  window.scrollBy(0,-10)
  }, 500);
var elementPosition = document.getElementById('id').offsetTop;

window.scrollTo({
  top: elementPosition - 10, //add your necessary value
  behavior: "smooth"  //Smooth transition to roll
});
它在MSIE11和Chrome 68+中工作得非常完美。我没有在FF考试。500毫秒是我敢说的最短的延迟时间。下降有时会失败,因为平滑滚动尚未完成。根据您自己的项目需要进行调整


+1以获得此简单但有效的解决方案。

假设您希望滚动到DOM中处于同一级别且类名为“随偏移量滚动”的div,则此CSS将解决此问题:

.scroll-with-offset {    
  padding-top: 100px;
  margin-bottom: -100px;
}
从页面顶部的偏移量为100px。它只能在“开始”块中按预期工作:

element.scrollIntoView({ behavior: 'smooth', block: 'start' });
发生的事情是,div的顶点在正常位置,但其内部内容开始低于正常位置100px。这就是padding top:100px的用途。保证金底部:-100px用于抵消下方div的额外保证金。 要使解决方案完整,还应添加此CSS以抵消最顶部和最底部div的边距/填充:

.top-div {
  padding-top: 0;
}
.bottom-div {
  margin-bottom: 0;
}

我有这个,它对我非常有效:

// add a smooth scroll to element
scroll(el) {
el.scrollIntoView({
  behavior: 'smooth',
  block: 'start'});

setTimeout(() => {
window.scrollBy(0, -40);
}, 500);}

希望有帮助。

这对我来说在Chrome上很有用(平滑滚动,没有计时障碍)

它只是移动元素,启动滚动,然后将其向后移动

如果元素已经在屏幕上,则不会出现可见的“弹出”

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;

我的主要想法是在要滚动到的视图上方创建一个tempDiv。它在我的项目中运行良好,没有滞后

scrollToView = (element, offset) => {
    var rect = element.getBoundingClientRect();
    var targetY = rect.y + window.scrollY - offset;

    var tempDiv;
    tempDiv = document.getElementById("tempDiv");
    if (tempDiv) {
        tempDiv.style.top = targetY + "px";
    } else {
        tempDiv = document.createElement('div');
        tempDiv.id = "tempDiv";
        tempDiv.style.background = "#F00";
        tempDiv.style.width = "10px";
        tempDiv.style.height = "10px";
        tempDiv.style.position = "absolute";
        tempDiv.style.top = targetY + "px";
        document.body.appendChild(tempDiv);
    }

    tempDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
使用的示例

onContactUsClick = () => {
    this.scrollToView(document.getElementById("contact-us"), 48);
}
希望它能帮助您顺利地滚动到正确的位置 获取正确的
y
坐标并使用
窗口。滚动到({top:y,behavior:'smooth')


根据Arseniy II的回答:我有一个用例,滚动实体不是窗口本身,而是一个内部模板(在本例中是一个div)。在这种情况下,我们需要为滚动容器设置一个ID,并通过
getElementById
获取该ID以使用其滚动功能:


...
const yOffsetForScroll=-100
const y=document.getElementById(this.idToScroll.getBoundingClientRect().top;
const main=document.getElementById('app-content');
main.scrollTo({
顶部:y+main.scrollTop+yOffsetForScroll,
行为:“平滑”
});
把它留在这里,以防有人面临类似的情况

这是我的2美分

我还遇到了scrollIntoView滚动过元素的问题,因此我创建了一个脚本(本机javascript),它将一个元素前置到目标,用css将其定位到顶部,然后滚动到该元素。滚动之后,我再次删除创建的元素

HTML:


希望这对任何人都有帮助

我用

element.scrollIntoView({behavior:'smooth',block:'center'});
这使得元素在滚动后出现在
中心
,因此我不必计算
yOffset


希望它能帮助…

我为那些没有通过上述解决方案解决此问题的人添加了此css提示:

#myDiv::before {
  display: block;
  content: " ";
  margin-top: -90px; // adjust this with your header height
  height: 90px; // adjust this with your header height
  visibility: hidden;
}
UPD:我创建了一个比下面的解决方案更有效、更易于使用的解决方案。 我的平滑滚动功能 我采用了Steve Banton的绝妙解决方案,并编写了一个函数,使其使用更加方便。使用
window.scroll()
甚至
window.scrollBy()
,就像我以前尝试过的那样,会更容易一些,但这两个都有一些问题:

  • 所有东西在使用后都会变得很垃圾,并且在屏幕上表现得很流畅
  • 你无论如何也无法阻止它们,只能等到卷轴的和。 因此,我希望我的函数对您有用。此外,还有一种方法可以使它在Safari甚至IE中工作
这是密码 只要把它复制下来,想怎么做就怎么做

从“smoothscroll polyfill”导入smoothscroll;
smoothscroll.polyfill();
const preparesmoothroll=linkEl=>{
常数额外_偏移=0;
const destinationEl=document.getElementById(linkEl.dataset.smoothScrollTo);
const blockOption=linkEl.dataset.smoothScrollBlock | | |“开始”;
if((blockOption=='start'| | blockOption==='end')&&EXTRA_偏移量){
const anchorEl=document.createElement('div');
destinationEl.setAttribute('style','position:relative;');
anchorEl.setAttribute('styl
const id = 'profilePhoto';
const yOffset = -10; 
const element = document.getElementById(id);
const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;

window.scrollTo({top: y, behavior: 'smooth'});
//anchor tag that appears multiple times on the page
<a href="#" class="anchors__link js-anchor" data-target="schedule">
    <div class="anchors__text">
        Scroll to the schedule
    </div>
</a>

//The node we want to scroll to, somewhere on the page
<div id="schedule">
    //html
</div>
(() => {
    'use strict';

    const anchors = document.querySelectorAll('.js-anchor');

    //if there are no anchors found, don't run the script
    if (!anchors || anchors.length <= 0) return;

    anchors.forEach(anchor => {
        //get the target from the data attribute
        const target = anchor.dataset.target;

        //search for the destination element to scroll to
        const destination = document.querySelector(`#${target}`);
        //if the destination element does not exist, don't run the rest of the code
        if (!destination) return;

        anchor.addEventListener('click', (e) => {
            e.preventDefault();
            //create a new element and add the `anchors__generated` class to it
            const generatedAnchor = document.createElement('div');
            generatedAnchor.classList.add('anchors__generated');

            //get the first child of the destination element, insert the generated element before it. (so the scrollIntoView function scrolls to the top of the element instead of the bottom)
            const firstChild = destination.firstChild;
            destination.insertBefore(generatedAnchor, firstChild);

            //finally fire the scrollIntoView function and make it animate "smoothly"
            generatedAnchor.scrollIntoView({
                behavior: "smooth",
                block: "start",
                inline: "start"
            });

            //remove the generated element after 1ms. We need the timeout so the scrollIntoView function has something to scroll to.
            setTimeout(() => {
                destination.removeChild(generatedAnchor);
            }, 1);
        })
    })
})();
.anchors__generated {
    position: relative;
    top: -100px;
}
#myDiv::before {
  display: block;
  content: " ";
  margin-top: -90px; // adjust this with your header height
  height: 90px; // adjust this with your header height
  visibility: hidden;
}
var elementPosition = document.getElementById('id').offsetTop;

window.scrollTo({
  top: elementPosition - 10, //add your necessary value
  behavior: "smooth"  //Smooth transition to roll
});
scroll(el: HTMLElement) {
  el.scrollIntoView({ block: 'start',  behavior: 'smooth' });   
}
<button (click)="scroll(target)"></button>
<div  #target style="margin-top:-50px;padding-top: 50px;" ></div>
function _scrollTo(selector, yOffset = 0){
  const el = document.querySelector(selector);
  const y = el.getBoundingClientRect().top + window.pageYOffset + yOffset;

  window.scrollTo({top: y, behavior: 'smooth'});
}
_scrollTo('#question-header', 0);
const element = document.getElementById("element-with-scroll");
element.scrollTop = element.scrollHeight - 10;
<html>
<head>
    <title>Scrolling Into View</title>
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <style>
        div.scroll { height: 6em; width: 20em; overflow: auto; }
        thead th   { position: sticky; top: -1px; background: #fff; }
        .up, .down { cursor: pointer; }
        .up:hover, .down:hover { color: blue; text-decoration:underline; }
    </style>
</head>
<body>
<div class='scroll'>
<table border='1'>
    <thead>
        <tr>
            <th>Review</th>
            <th>Data</th>
        </tr>
    </thead>
    <tbody>
        <tr id='row_1'>
            <th></th>
            <td>Row 1 (OK)</td>
        </tr>
        <tr id='row_2'>
            <th></th>
            <td>Row 2 (OK)</td>
        </tr>
        <tr id='row_3'>
            <th id='jump_1'><span class='up'>UP</span> <span class='down'>DN</span></th>
            <td>Row 3 (REVIEW)</td>
        </tr>
        <tr id='row_4'>
            <th></th>
            <td>Row 4 (OK)</td>
        </tr>
        <tr id='row_5'>
            <th id='jump_2'><span class='up'>UP</span> <span class='down'>DN</span></th>
            <td>Row 5 (REVIEW)</td>
        </tr>
        <tr id='row_6'>
            <th></th>
            <td>Row 6 (OK)</td>
        </tr>
        <tr id='row_7'>
            <th></th>
            <td>Row 7 (OK)</td>
        </tr>
        <tr id='row_8'>
            <th id='jump_3'><span class='up'>UP</span> <span class='down'>DN</span></th>
            <td>Row 8 (REVIEW)</td>
        </tr>
        <tr id='row_9'>
            <th></th>
            <td>Row 9 (OK)</td>
        </tr>
        <tr id='row_10'>
            <th></th>
            <td>Row 10 (OK)</td>
        </tr>
    </tbody>
</table>
</div>
<script>
$(document).ready( function() {
    $('.up').on('click', function() {
        var id = parseInt($(this).parent().attr('id').split('_')[1]);
        if (id>1) {
            var row_id = $('#jump_' + (id - 1)).parent().attr('id').split('_')[1];
            document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
        } else {
            alert('At first');
        }
    });

    $('.down').on('click', function() {
        var id = parseInt($(this).parent().attr('id').split('_')[1]);
        if ($('#jump_' + (id + 1)).length) {
            var row_id = $('#jump_' + (id + 1)).parent().attr('id').split('_')[1];
            document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
        } else {
            alert('At last');
        }
    });
});
</script>
</body>
</html>
                document.activeElement.parentElement.parentElement.scrollIntoView({block: 'center', behavior: 'smooth'}); 
                document.activeElement.scrollIntoView({block: 'center', behavior: 'smooth'});