如何滚动到div内的元素?

IT技术 javascript html scroll
2021-01-28 19:28:26

我有一个滚动div,当我点击它时我想有一个事件,它会强制div滚动以查看里面的元素。我这样写它的 JavasSript:

document.getElementById(chr).scrollIntoView(true);

但这会在滚动div本身的同时滚动所有页面如何解决?

我想这样说: MyContainerDiv.getElementById(chr).scrollIntoView(true);

6个回答

您需要获取要滚动到视图中的元素相对于其父级(滚动 div 容器)的顶部偏移量:

var myElement = document.getElementById('element_within_div');
var topPos = myElement.offsetTop;

变量 topPos 现在设置为滚动 div 顶部与您希望可见的元素之间的距离(以像素为单位)。

现在我们告诉 div 使用scrollTop以下命令滚动到该位置

document.getElementById('scrolling_div').scrollTop = topPos;

如果你使用原型 JS 框架,你会做同样的事情:

var posArray = $('element_within_div').positionedOffset();
$('scrolling_div').scrollTop = posArray[1];

同样,这将滚动 div,以便您希望看到的元素正好位于顶部(或者,如果不可能,则尽可能向下滚动以使其可见)。

请注意,请求myElement.offsetTop会触发回流(布局颠簸),这可能是性能瓶颈
2021-03-18 19:28:26
这真的很有帮助!如果要多次设置滚动,则需要根据当前滚动位置进行偏移。这是我在 jQuery 中的做法: $('#scrolling_div').scrollTop($('#scrolling_div').scrollTop() + $('#element_within_div').position().top);
2021-03-19 19:28:26
在 2017 年仍然有效。附加信息:.offsetTop 可能返回 0。然后您应该引用父元素并重试。我这样做了标记h4,然后divarticle标签,只article为我工作。
2021-03-30 19:28:26
请记住使用 css 设置滚动父级:position: relative否则您将像我刚才那样花费大量时间进行调试。
2021-04-03 19:28:26
我必须为父元素 ( )设置overflow-y属性,否则它不起作用。属性的默认 css 值,即使它也使手动滚动成为可能,但 js 代码不起作用(即使使用..)scrollscrolling_divoverflowauto{psition: relative}
2021-04-10 19:28:26

您必须在要滚动到的 DIV 中找到元素的位置,并设置 scrollTop 属性。

divElem.scrollTop = 0;

更新

向上或向下移动的示例代码

  function move_up() {
    document.getElementById('divElem').scrollTop += 10;
  }

  function move_down() {
    document.getElementById('divElem').scrollTop -= 10;
  }
我想滚动它视图,以查看它不以特定值滚动
2021-04-05 19:28:26

方法 1 - 平滑滚动到元素内的元素

var box = document.querySelector('.box'),
    targetElm = document.querySelector('.boxChild'); // <-- Scroll to here within ".box"

document.querySelector('button').addEventListener('click', function(){
   scrollToElm( box, targetElm , 600 );   
});


/////////////

function scrollToElm(container, elm, duration){
  var pos = getRelativePos(elm);
  scrollTo( container, pos.top , 2);  // duration in seconds
}

function getRelativePos(elm){
  var pPos = elm.parentNode.getBoundingClientRect(), // parent pos
      cPos = elm.getBoundingClientRect(), // target pos
      pos = {};

  pos.top    = cPos.top    - pPos.top + elm.parentNode.scrollTop,
  pos.right  = cPos.right  - pPos.right,
  pos.bottom = cPos.bottom - pPos.bottom,
  pos.left   = cPos.left   - pPos.left;

  return pos;
}
    
function scrollTo(element, to, duration, onDone) {
    var start = element.scrollTop,
        change = to - start,
        startTime = performance.now(),
        val, now, elapsed, t;

    function animateScroll(){
        now = performance.now();
        elapsed = (now - startTime)/1000;
        t = (elapsed/duration);

        element.scrollTop = start + change * easeInOutQuad(t);

        if( t < 1 )
            window.requestAnimationFrame(animateScroll);
        else
            onDone && onDone();
    };

    animateScroll();
}

function easeInOutQuad(t){ return t<.5 ? 2*t*t : -1+(4-2*t)*t };
.box{ width:80%; border:2px dashed; height:180px; overflow:auto; }
.boxChild{ 
  margin:600px 0 300px; 
  width: 40px;
  height:40px;
  background:green;
}
<button>Scroll to element</button>
<div class='box'>
  <div class='boxChild'></div>
</div>

方法 2 - 使用Element.scrollIntoView

请注意,浏览器支持不是很好

var targetElm = document.querySelector('.boxChild'),  // reference to scroll target
    button = document.querySelector('button');        // button that triggers the scroll
  
// bind "click" event to a button 
button.addEventListener('click', function(){
   targetElm.scrollIntoView()
})
.box {
  width: 80%;
  border: 2px dashed;
  height: 180px;
  overflow: auto;
  scroll-behavior: smooth; /* <-- for smooth scroll */
}

.boxChild {
  margin: 600px 0 300px;
  width: 40px;
  height: 40px;
  background: green;
}
<button>Scroll to element</button>
<div class='box'>
  <div class='boxChild'></div>
</div>

方法 3 - 使用 CSS滚动行为

.box {
  width: 80%;
  border: 2px dashed;
  height: 180px;
  overflow-y: scroll;
  scroll-behavior: smooth; /* <--- */
}

#boxChild {
  margin: 600px 0 300px;
  width: 40px;
  height: 40px;
  background: green;
}
<a href='#boxChild'>Scroll to element</a>
<div class='box'>
  <div id='boxChild'></div>
</div>

请注意,IE/Edge/Safari 不支持滚动行为
2021-03-26 19:28:26
@sheats - 它在我以大字体放置的 MDN 文档链接中完全说明了这一点。即使它不适用于那些浏览器,也不意味着您不应该使用它。没有“规则”,所有浏览器上的所有行为都必须相同。如果现代浏览器能变魔术,那就让它们变魔术吧。
2021-04-01 19:28:26
@DoMiNeLa10 - 这是一个假设。OP 可能提供了一个任意示例来说明他/她的问题。此外,OP 不是主要关注点,而是来自搜索引擎的人们正在寻找健康的解决方案,并且很可能专门针对 OP 需求做出回答对他们无济于事,本网站的目的是创建可靠的答案,以帮助尽可能多的人尽可能。我的回答提供了两者
2021-04-04 19:28:26
这篇文章是关于滚动整个文档而不是可滚动元素。
2021-04-09 19:28:26

原生 JS、跨浏览器、平滑滚动(2020 年更新)

设置ScrollTop确实提供了所需的结果,但滚动非常突然。使用jquery平滑滚动不是一种选择。所以这里有一种支持所有主要浏览器的本地方式来完成工作。参考 - caniuse

// get the "Div" inside which you wish to scroll (i.e. the container element)
const El = document.getElementById('xyz');

// Lets say you wish to scroll by 100px, 
El.scrollTo({top: 100, behavior: 'smooth'});

// If you wish to scroll until the end of the container
El.scrollTo({top: El.scrollHeight, behavior: 'smooth'});

而已!


这是一个可疑的工作片段 -

document.getElementById('btn').addEventListener('click', e => {
  e.preventDefault();
  // smooth scroll
  document.getElementById('container').scrollTo({top: 175, behavior: 'smooth'});
});
/* just some styling for you to ignore */
.scrollContainer {
  overflow-y: auto;
  max-height: 100px;
  position: relative;
  border: 1px solid red;
  width: 120px;
}

body {
  padding: 10px;
}

.box {
  margin: 5px;
  background-color: yellow;
  height: 25px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#goose {
  background-color: lime;
}
<!-- Dummy html to be ignored -->
<div id="container" class="scrollContainer">
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div id="goose" class="box">goose</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
</div>

<button id="btn">goose</button>

更新:正如您在评论Element.scrollTo()中所见,IE11似乎不支持。所以如果你不关心 IE11(你真的不应该),请随意在你的所有项目中使用它。请注意,存在对 Edge 的支持!所以你并没有真正把你的 Edge/Windows 用户抛在后面;)

参考

根据caniuse 的说法,它在 IE11 和 Edge 中受支持。没有在这些浏览器上亲自测试过,但似乎是支持的。
2021-03-19 19:28:26
你说的对。不支持 IE11。但是似乎支持Edge v76 (ref)及更高版本
2021-03-25 19:28:26
scrollTo()可能在所有主要浏览器中都支持Window对象,但在 IE 或 Edge 中不支持元素。
2021-03-29 19:28:26
那是window.scrollTo,不是Element.scrollTo例如,在 Edge 中试试这个,并检查控制台:codepen.io/timdown/pen/abzVEMB
2021-04-03 19:28:26

要将元素滚动到 div 的视图中,仅在需要时,您可以使用此scrollIfNeeded功能:

function scrollIfNeeded(element, container) {
  if (element.offsetTop < container.scrollTop) {
    container.scrollTop = element.offsetTop;
  } else {
    const offsetBottom = element.offsetTop + element.offsetHeight;
    const scrollBottom = container.scrollTop + container.offsetHeight;
    if (offsetBottom > scrollBottom) {
      container.scrollTop = offsetBottom - container.offsetHeight;
    }
  }
}

document.getElementById('btn').addEventListener('click', ev => {
  ev.preventDefault();
  scrollIfNeeded(document.getElementById('goose'), document.getElementById('container'));
});
.scrollContainer {
  overflow-y: auto;
  max-height: 100px;
  position: relative;
  border: 1px solid red;
  width: 120px;
}

body {
  padding: 10px;
}

.box {
  margin: 5px;
  background-color: yellow;
  height: 25px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#goose {
  background-color: lime;
}
<div id="container" class="scrollContainer">
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div id="goose" class="box">goose</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
</div>

<button id="btn">scroll to goose</button>

这真的很有帮助。我有点挣扎,因为我错过了位置:容器上的相对位置。这很关键!
2021-03-26 19:28:26