如何将DIV水平滚动到容器的中心?

如何将DIV水平滚动到容器的中心?

问题描述:

我有一个有2个DIV的容器。当我点击一个按钮时,我试图将黄色DIV水平放置在容器中。但是,如果我多次单击按钮,它会前后滚动,如果手动滚动容器然后单击该按钮,则黄色DIV永远不会滚动到视图中。如何将DIV水平滚动到容器的中心?

这里是jsfiddle。如果你反复点击按钮,它会来回滚动。为什么会这样?: https://jsfiddle.net/nug4urna/

HTML:

<div id='container'> 
<div id='blue'></div> 
<div id='yellow'></div> 
</div> 
<div id='mybutton'> 
click to scroll yellow div into view 
</div> 
<div id='log'> 
</div> 

JAVSCRIPT:

function scrollDivIntoView(id) { 
     var elOffset = $(id).offset().left; 
     var elWidth = $(id).width(); 
     var containerWidth = $('#container').width(); 
     var offset = elOffset - ((containerWidth - elWidth)/2); 

     $('#container').scrollLeft(offset); 

     var _log = 'elOffset = ' + elOffset + '<br>'; 
     _log += 'elWidth = ' + elWidth + '<br>'; 
     _log += 'containerWidth = ' + containerWidth + '<br>'; 
     _log += 'offset = ' + offset; 

     $('#log').html(_log); 
} 

$(document).ready(function() { 
    $('body').on('click', '#mybutton', function(){ 
     scrollDivIntoView('#yellow'); 
    }); 
}); 

CSS:

#container{ 
    width:100%; 
    height:150px; 
    border:1px solid red; 
    display:inline-block; 
    white-space:nowrap; 
    overflow-y:hidden; 
    overflow-x:auto; 
} 
#blue{ 
    width:2000px; 
    height:100px; 
    background-color: blue; 
    margin:5px; 
    display:inline-block; 
} 
#yellow{ 
    width:200px; 
    height:100px; 
    background-color: yellow; 
    margin:5px; 
    display:inline-block; 
} 
#mybutton{ 
    margin-top:10px; 
    cursor:pointer; 
    background-color:black; 
    color:white; 
    width:400px; 
    padding:4px; 
    text-align:center; 
} 

如果您将第一行更改为var elOffset = $(id)[0].offsetLeft;,则原始代码在每种情况下都适用。

更多信息请参阅以下内容: https://javascript.info/size-and-scroll

+0

即使我想出了一个'黑客'让它在很久以前开始工作,我会接受这个答案。我的解决方案是在执行计算之前将容器scrollLeft设置回0,所以我真的滚动了两次,它发生得很快,甚至没有看到它。但你的解决方案更好。 –

要居中,你需要添加您的黄色容器的右边缘可以“填充”右侧并使其居中。我更新了你的提琴: https://jsfiddle.net/nug4urna/2/

#yellow{ 
    width:200px; 
    height:100px; 
    background-color: yellow; 
    margin:5px; 
    display:inline-block; 
    margin-right: 100%; 
} 

而且它跳跃来回是因为计算是基于每次点击后改变了var elOffset = $(id).offset().left;的原因。我更新了小提琴,以检查偏移量是否大于容器宽度。如果更少,我们会阻止更新。

if (elOffset > containerWidth) { 
    $('#container').scrollLeft(offset); 
    } 

UPDATE: 这工作第一次,但如果用户滚动计算是不完全正确。您应该查看https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollWidth以帮助计算滚动条实际移动的距离。这意味着当栏一直移动到右侧以显示所有内容时,数值与总宽度不一样。

+0

好了,你的jsfiddle有错误:'如果(elOffeset> containerWidth){'应该是'如果(elOffset> containerWidth){'。你是对的,它第一次工作,但是确实有办法让它工作,即使用户滚动? –

+0

抱歉,错字。更新小提琴以使用全局来追踪初始偏移量。 https://jsfiddle.net/nug4urna/4/ – RickTakes

+0

虽然这对我来说不起作用,因为我的问题实际上比我在简单示例中展现的还要多。我会将div附加到容器中,这样所有的数字都会改变。我没有把这个加到我的例子中,因为即使宽度改变它仍然应该是相同的计算。 –