英文:
How to scroll an element into horizontal center?
问题
我有一堆图片放在一个展示窗口里,每当按下任何一张图片时,我希望它滚动到水平中心。
我尝试了.scrollIntoView()
,但问题是整个页面也随之滚动,而不仅仅是展示窗口。
我已经使用scrollTo()
成功了,但似乎不能完美地将图像对齐到中心:
请问有人可以告诉我为什么会发生这种情况吗?我甚至考虑了边距和宽度
(如果能实现最终目标,我愿意改变我的方法)
const showcase = document.querySelector(".showcase");
const move_img = (by) => {
const img = showcase.querySelector("img");
const style = window.getComputedStyle(img);
showcase.scrollTo({
top: 0,
left: (parseInt(style.width) + parseInt(style.marginLeft)) * (by - 1),
behavior: "smooth",
});
}
Array.from(showcase.children).forEach((child, index) => {
child.onclick = () => {
move_img(index, true);
}
});
:root {
--main_pic_width: 30rem;
--showcase_height: 5rem;
--showcase_division: 3;
--showcase_gap: 1rem;
}
.showcase {
width: calc(var(--main_pic_width) + var(--showcase_gap));
height: var(--showcase_height);
background: gray;
white-space: nowrap;
overflow-y: hidden;
overflow-x: auto;
-ms-overflow-style: none;
scrollbar-width: none;
}
.showcase::-webkit-scrollbar {
display: none;
}
.showcase img {
width: calc(var(--main_pic_width) / var(--showcase_division) - var(--showcase_gap));
background-color: black;
margin-left: var(--showcase_gap);
object-fit: contain;
}
<div class="showcase">
<img src="https://www.w3schools.com/css/img_forest.jpg" />
<img src="https://www.w3schools.com/css/img_5terre.jpg" />
<img src="https://www.w3schools.com/css/img_mountains.jpg" />
<img src="https://www.w3schools.com/css/img_lights.jpg" />
<img src="https://www.w3schools.com/css/img_5terre.jpg" />
<img src="https://www.w3schools.com/css/img_forest.jpg" />
<img src="https://www.w3schools.com/css/img_mountains.jpg" />
</div>
<details>
<summary>英文:</summary>
I have a bunch of pictures within a showcase and Whenever any picture is pressed
I would like it to scroll to the horizontal center
I tried `.scrollIntoView()` but the problem was that the entire page was scrolling with it instead of just the showcase
I've managed to use `scrollTo()` but it doesn't seem to perfectly align the image to the center:
[![enter image description here][1]][1]
Can someone please tell me why this is happening? I even took margin and width into calculation
(I'm open to changing my approach if it achieves the ultimate goal)
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const showcase=document.querySelector(".showcase")
const move_img=(by)=>{
const img=showcase.querySelector("img")
const style=window.getComputedStyle(img);
showcase.scrollTo({
top: 0,
left: (parseInt(style.width) + parseInt(style.marginLeft)) * (by - 1 ),
behavior: "smooth",
});
/*
showcase.children[index].scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'center'
});
*/
}
Array.from(showcase.children).forEach((child, index) => {
child.onclick=()=>{move_img(index, true)}
});
<!-- language: lang-css -->
:root{
--main_pic_width:30rem;
--showcase_height:5rem;
--showcase_division:3;
--showcase_gap:1rem;
}
.showcase{
width:calc( var(--main_pic_width) + var(--showcase_gap));
height:var(--showcase_height);
background:gray;
white-space:nowrap;
overflow-y:hidden;
overflow-x:auto;
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
}
.showcase::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
.showcase img{
width:calc( var(--main_pic_width)/var(--showcase_division) - var(--showcase_gap));
background-color:black;
margin-left:var(--showcase_gap);
object-fit: contain;
}
<!-- language: lang-html -->
<div class="showcase">
<img src="https://www.w3schools.com/css/img_forest.jpg" />
<img src="https://www.w3schools.com/css/img_5terre.jpg"/>
<img src="https://www.w3schools.com/css/img_mountains.jpg"/>
<img src="https://www.w3schools.com/css/img_lights.jpg"/>
<img src="https://www.w3schools.com/css/img_5terre.jpg"/>
<img src="https://www.w3schools.com/css/img_forest.jpg"/>
<img src="https://www.w3schools.com/css/img_mountains.jpg"/>
</div>
<!-- end snippet -->
[1]: https://i.stack.imgur.com/QcHpD.png
</details>
# 答案1
**得分**: 2
你可以使用 `offsetLeft` 和 `offsetWidth` 来计算要滚动到的位置。
```javascript
const showcase = document.querySelector(".showcase");
showcase.addEventListener('click', e => {
if (e.target.matches('img'))
showcase.scroll({left: e.target.offsetLeft - (showcase.offsetWidth - e.target.offsetWidth) / 2, behavior: 'smooth'});
});
:root{
--main_pic_width:30rem;
--showcase_height:5rem;
--showcase_division:3;
--showcase_gap:1rem;
}
.showcase{
width:calc( var(--main_pic_width) + var(--showcase_gap));
height:var(--showcase_height);
background:gray;
white-space:nowrap;
overflow-y:hidden;
overflow-x:auto;
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
}
.showcase::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
.showcase img{
width:calc( var(--main_pic_width)/var(--showcase_division) - var(--showcase_gap));
background-color:black;
margin-left:var(--showcase_gap);
object-fit: contain;
}
<div class="showcase">
<img src="https://www.w3schools.com/css/img_forest.jpg" />
<img src="https://www.w3schools.com/css/img_5terre.jpg"/>
<img src="https://www.w3schools.com/css/img_mountains.jpg"/>
<img src="https://www.w3schools.com/css/img_lights.jpg"/>
<img src="https://www.w3schools.com/css/img_5terre.jpg"/>
<img src="https://www.w3schools.com/css/img_forest.jpg"/>
<img src="https://www.w3schools.com/css/img_mountains.jpg"/>
</div>
英文:
You can calculate the position to scroll to using offsetLeft
and offsetWidth
.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const showcase = document.querySelector(".showcase");
showcase.addEventListener('click', e => {
if (e.target.matches('img'))
showcase.scroll({left: e.target.offsetLeft - (showcase.offsetWidth - e.target.offsetWidth) / 2, behavior: 'smooth'});
});
<!-- language: lang-css -->
:root{
--main_pic_width:30rem;
--showcase_height:5rem;
--showcase_division:3;
--showcase_gap:1rem;
}
.showcase{
width:calc( var(--main_pic_width) + var(--showcase_gap));
height:var(--showcase_height);
background:gray;
white-space:nowrap;
overflow-y:hidden;
overflow-x:auto;
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
}
.showcase::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
.showcase img{
width:calc( var(--main_pic_width)/var(--showcase_division) - var(--showcase_gap));
background-color:black;
margin-left:var(--showcase_gap);
object-fit: contain;
}
<!-- language: lang-html -->
<div class="showcase">
<img src="https://www.w3schools.com/css/img_forest.jpg" />
<img src="https://www.w3schools.com/css/img_5terre.jpg"/>
<img src="https://www.w3schools.com/css/img_mountains.jpg"/>
<img src="https://www.w3schools.com/css/img_lights.jpg"/>
<img src="https://www.w3schools.com/css/img_5terre.jpg"/>
<img src="https://www.w3schools.com/css/img_forest.jpg"/>
<img src="https://www.w3schools.com/css/img_mountains.jpg"/>
</div>
<!-- end snippet -->
答案2
得分: 0
@Unmitigated的答案有效,但由于某种原因,在生产环境中未能正常工作,也许是我忽略了一些边距或填充?
不管怎样,我找到了解决方案:
<div class="showcase">
<img src="https://www.w3schools.com/css/img_forest.jpg" />
<img src="https://www.w3schools.com/css/img_5terre.jpg" />
<img src="https://www.w3schools.com/css/img_mountains.jpg" />
<img src="https://www.w3schools.com/css/img_lights.jpg" />
<img src="https://www.w3schools.com/css/img_5terre.jpg" />
<img src="https://www.w3schools.com/css/img_forest.jpg" />
<img src="https://www.w3schools.com/css/img_mountains.jpg" />
</div>
:root {
--main_pic_width: 30rem;
--showcase_height: 5rem;
--showcase_division: 3;
--showcase_gap: 1rem;
}
.showcase {
width: var(--main_pic_width);
height: var(--showcase_height);
background: gray;
white-space: nowrap;
overflow-y: hidden;
overflow-x: auto;
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
}
.showcase::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
.showcase img {
height: 100%;
width: calc(
(var(--main_pic_width) - var(--showcase_gap) * var(--showcase_division) * 2) /
var(--showcase_division)
);
margin: 0 var(--showcase_gap);
object-fit: contain;
box-sizing: border-box;
}
const showcase = document.querySelector(".showcase");
const move_img = (by) => {
const img = showcase.querySelector("img");
const style = window.getComputedStyle(img);
showcase.scrollTo({
top: 0,
left:
(parseInt(style.width) +
parseInt(style.marginLeft) +
parseInt(style.marginRight)) *
(by - 1),
behavior: "smooth",
});
};
Array.from(showcase.children).forEach((child, index) => {
child.onclick = () => {
move_img(index, true);
};
});
此外,所有<img>
标签都在同一行中的原因是,添加换行会在2个图像之间创建空格,从而破坏了计算。
英文:
@Unmitigated's answer works but for some reason it didn't work in production
perhaps some margin or padding I missed?
regardless I found the solution:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const showcase=document.querySelector(".showcase")
const move_img=(by)=>{
const img=showcase.querySelector("img")
const style=window.getComputedStyle(img);
showcase.scrollTo({
top: 0,
left: (parseInt(style.width) + parseInt(style.marginLeft) + parseInt(style.marginRight)) * (by - 1 ),
behavior: "smooth",
});
}
Array.from(showcase.children).forEach((child, index) => {
child.onclick=()=>{move_img(index, true)}
});
<!-- language: lang-css -->
:root{
--main_pic_width:30rem;
--showcase_height:5rem;
--showcase_division:3;
--showcase_gap:1rem;
}
.showcase{
width:var(--main_pic_width);
height:var(--showcase_height);
background:gray;
white-space:nowrap;
overflow-y:hidden;
overflow-x:auto;
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
}
.showcase::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
.showcase img{
height: 100%;
width: calc( (var(--main_pic_width) - var(--showcase_gap) * var(--showcase_division) * 2) / var(--showcase_division));
margin: 0 var(--showcase_gap);
object-fit: contain;
box-sizing: border-box;
}
<!-- language: lang-html -->
<div class="showcase">
<img src="https://www.w3schools.com/css/img_forest.jpg" /><img src="https://www.w3schools.com/css/img_5terre.jpg"/><img src="https://www.w3schools.com/css/img_mountains.jpg"/><img src="https://www.w3schools.com/css/img_lights.jpg"/><img src="https://www.w3schools.com/css/img_5terre.jpg"/><img src="https://www.w3schools.com/css/img_forest.jpg"/><img src="https://www.w3schools.com/css/img_mountains.jpg"/> -->
</div>
<!-- end snippet -->
Also the reason all the <img>
tags are in a single line is because adding a newline creates a space in between 2 images which messes up the calculation
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论