在 DOM 更改后,向后滚动,以便参考元素在屏幕上的位置与 DOM 更改发生之前的位置相同

我有一个用户移动东西的应用程序。在他或她这样做之后,我想将屏幕重新定位到之前的位置以减少混乱。为此,我想自动滚动,以便在 DOM 移动之前将参考元素定位在屏幕上的同一位置。


我创建了一个代码笔来隔离和重现我的应用程序的问题:https : //codepen.io/VincentBlouin/pen/YzzMKxm


let centerTextDiv = document.getElementById('center-text');

let scrollDiv = document.getElementById('scrollable');


centerRect = centerTextDiv.getBoundingClientRect();


scrollDiv.scrollLeft = centerRect.x - (centerRect.width / 2);

scrollDiv.scrollTop = centerRect.y - (centerRect.height + 75);


let firstTextDiv = document.getElementById('first-div-text');


let firstText = firstTextDiv.textContent;

let firstChars = firstText.substr(0, 500);

let lastChars = firstText.substr(500, firstText.length);



let insertNewTextDiv = document.getElementById('insert-new-text');



setTimeout(()=>{

  firstTextDiv.innerHTML = firstChars;

  insertNewTextDiv.innerHTML = lastChars;

  //scroll here

}, 3000);

首先参考 div 是可见的,但 3 秒后一些文本被移动并且参考 div 在屏幕上不再可见。


在我的真实应用程序中,滚动容器只是 document.scrollingElement,但我必须在代码笔中创建一个可滚动的 div。同样在我的应用程序 x,y 中,我的参考 div 的 getBoundingClientRect 在 DOM 更改之前和之后是不同的。


嗯,谢谢。我以为这很容易解决,但我感到困惑。


蝴蝶刀刀
浏览 176回答 2
2回答

呼唤远方

您需要重新计算新的滚动并#scrollable在 DOM 更改后应用它:// Get centerRect coordinates againcenterRect = centerTextDiv.getBoundingClientRect();centerRectMoveX = centerRect.x - (centerRect.width / 2);centerRectMoveY = centerRect.y - (centerRect.height + 75);// Apply to scrollDiv by adding it to the current valuescrollDiv.scrollLeft = scrollDiv.scrollLeft + centerRectMoveX;scrollDiv.scrollTop = scrollDiv.scrollTop + centerRectMoveY;这应该在 DOM chaging 函数中执行:setTimeout(()=>{  firstTextDiv.innerHTML = firstChars;  insertNewTextDiv.innerHTML = lastChars;  centerRect = centerTextDiv.getBoundingClientRect();  centerRectMoveX = centerRect.x - (centerRect.width / 2);  centerRectMoveY = centerRect.y - (centerRect.height + 75);  scrollDiv.scrollLeft = scrollDiv.scrollLeft + centerRectMoveX;  scrollDiv.scrollTop = scrollDiv.scrollTop + centerRectMoveY;}, 3000);在这个 JSFiddle 中检查它:https ://jsfiddle.net/esm280rq/

潇湘沐

getBoundingRect将随着滚动而改变,因此在这些计算中使用它有点困难。您可以简单地使用元素的偏移量来确定与 div 坐标的关系所需的滚动。您可以通过始终滚动到元素的offsetLeft和offsetTop来简化,即使绝对偏移量发生变化,它也应该始终保持相对于滚动元素的相同位置。然后如果你想居中,你只需要调整滚动元素的宽度和高度以及元素的宽度和高度。但是这些数字不会改变,重要的部分是跟随offsetLeft和offsetTop,它们是实际移动的数字。像这样:let centerTextDiv = document.getElementById('center-text');let scrollDiv = document.getElementById('scrollable');// here are the formulas. This centers your div in the scrollable.&nbsp;// Normally using the same formula will always position the element at the same position relative to the scroll element.// Here (scrollDiv.offsetWidth - centerTextDiv.offsetWidth) / 2 is to center, but only the offset left and top will change.scrollDiv.scrollLeft = (centerTextDiv.offsetLeft) - ((scrollDiv.offsetWidth - centerTextDiv.offsetWidth) / 2);scrollDiv.scrollTop = (centerTextDiv.offsetTop) - ((scrollDiv.offsetHeight - centerTextDiv.offsetHeight) / 2);let firstTextDiv = document.getElementById('first-div-text');let firstText = firstTextDiv.textContent;let firstChars = firstText.substr(0, 500);let lastChars = firstText.substr(500, firstText.length);let insertNewTextDiv = document.getElementById('insert-new-text');setTimeout(() => {&nbsp; firstTextDiv.innerHTML = firstChars;&nbsp; insertNewTextDiv.innerHTML = lastChars;&nbsp; scrollDiv.scrollLeft = (centerTextDiv.offsetLeft) - ((scrollDiv.offsetWidth - centerTextDiv.offsetWidth) / 2);&nbsp; scrollDiv.scrollTop = (centerTextDiv.offsetTop) - ((scrollDiv.offsetHeight - centerTextDiv.offsetHeight) / 2);}, 3000);#scrollable {&nbsp; width: 300px;&nbsp; height: 200px;&nbsp; overflow: scroll;}#main {&nbsp; display: flex;&nbsp; flex: 1 1 auto;&nbsp; flex-wrap: nowrap;}.flex-grow {&nbsp; display: flex;&nbsp; flex-grow: 1 !important;&nbsp; flex-shrink: 0;}.side-div {&nbsp; width: 250px;}#scroll-reference {&nbsp; align-items: center;&nbsp; justify-content: center;&nbsp; margin-left: 20px;&nbsp; margin-right: 20px;}#insert-new-text {&nbsp; max-width: 400px;}<div id="scrollable">&nbsp; <div id="main">&nbsp; &nbsp; <div class='flex-grow'>&nbsp; &nbsp; &nbsp; <div class='side-div' id='first-div-text'>&nbsp; &nbsp; &nbsp; &nbsp; left - At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; </div>&nbsp; &nbsp; <div id="scroll-reference" class='flex-grow'>&nbsp; &nbsp; &nbsp; <div id="center-text">text move in 3 seconds</div>&nbsp; &nbsp; </div>&nbsp; &nbsp; <div class='flex-grow'>&nbsp; &nbsp; &nbsp; <div class='side-div'>&nbsp; &nbsp; &nbsp; &nbsp; At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat&nbsp; &nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; <div class='flex-grow'>&nbsp; &nbsp; &nbsp; &nbsp; <div id="insert-new-text"></div>&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; </div>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript