javascript - 为什么切换 flex-direction 时顺序最低的元素会滚动到视口(viewport)中?

标签 javascript html css flexbox

我有一个用 CSS FlexBox 完成的列表。我已经根据一些标准 order 分配给所有 flexbox items,所以列表是视觉排序的。我还有一个按钮可以切换 flexbox containerflex-direction,所以我可以恢复显示顺序。我的空间有限,所以使用 overflow-y: scroll; 并且当我使用 flex-direction 恢复列表的视觉顺序时,带有 order 的元素: 1 正在滚动到视口(viewport)中。所以当它在顶部时 (flex-direction: column;) - 在容器的开头滚动(列表中有 10 个元素),

但是当我应用 flex-direction: column-reverse; - 我仍然可以看到这个元素,但现在滚动在容器的底部:

为什么滚动会跟随具有最低 order 属性的元素?

这是我在 Relative codepen 中的代码或内联在下面

HTML

<div class="alternator">
  <button>Reverse order</button>
</div>

<div class="wrapper">
  <div class="item a10">10 away</div>
  <div class="item a2">2 upon</div>
  <div class="item a3">3 a</div>
  <div class="item a4">4 time</div>
  <div class="item a5">5 in</div>
  <div class="item a6">6 a</div>
  <div class="item a7">7 galaxy</div>
  <div class="item a1">1 once</div>
  <div class="item a8">8 very</div>
  <div class="item a9">9 far</div>
</div>

CSS

.wrapper {
  display: flex;
  flex-direction: column;
  overflow-y: scroll;
  max-height: 350px;
  border: 2px solid green;
  width: 150px;
}

.wrapper.reversed {
  flex-direction: column-reverse;
}

.item {
  height: 30px;
  padding: 20px;
}

.a1{order: 1;}
.a2{order: 2;}
.a3{order: 3;}
.a4{order: 4;}
.a5{order: 5;}
.a6{order: 6;}
.a7{order: 7;}
.a8{order: 8;}
.a9{order: 9;}
.a10{order: 10;}

button {
  margin-bottom: 20px;
  width: 150px;
  height: 30px;
}

JS

const btn = document.querySelector('.alternator button');
const list = document.querySelector('.wrapper');

btn.addEventListener('click', () => {
  list.classList.toggle('reversed');
})

更新 由于下面的回答涉及滚动方面,我必须在此处添加 flex-direction: *-reverse 的工作方式类似于 order 属性 -即仅在视觉上改变元素的顺序,因此 DOM 树中的第一个元素在渲染后保留在那里:

“Note: The reordering capabilities of flex layout intentionally affect only the visual rendering, leaving speech order and navigation based on the source order. This allows authors to manipulate the visual presentation while leaving the source order intact for non-CSS UAs and for linear models such as speech and sequential navigation.” - Ordering and Orientation

Reference from MDN .

最佳答案

我不确定为什么会这样,但我认为这与滚动以这种方式工作有关 - 它从 DOM 中的第一个元素开始。

根据关于滚动目标的 MDN(https://developer.mozilla.org/en-US/docs/Web/Events/scroll):

The event target (the topmost target in the DOM tree).

但这里有一个小技巧可以解决它:

将元素 0 添加到列表顶部 <div class="item a0">000</div>然后执行以下操作:

btn.addEventListener('click', () => {
    list.classList.toggle('reversed');
    if(list.classList.contains('reversed') ){
        list.children[0].style.order = 100;
    } else {
        list.children[0].style.order = 0;
    }
    list.children[0].scrollIntoView();
});

关于javascript - 为什么切换 flex-direction 时顺序最低的元素会滚动到视口(viewport)中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50812999/

相关文章:

javascript - 如何在 JavaScript 中自发获取多个输入

javascript - 如果父事件已经运行超过一段时间,如何运行函数

php - 字符在数据库中存储为奇怪的字符,但在 HTML 中正确呈现

html - 让灵活的列在 Safari 和 iPhone Chrome 中工作

jquery - 使用 'background-size: cover' 更改高度时 IE 图像问题

javascript - 谷歌地图 API v3 如何获取所有形状的坐标

javascript - HTML输入只接受0-9(英文数字)和০-৯(孟加拉语数字)?

javascript - 是否可以更改整个 css 类/js 以及与之相关的任何内容?

Html 编辑页面内容

html - 我使用 nav 标签的菜单不适合整个页面,只占屏幕的一半