如何通过订单号定位弹性项目?
How to target flex item by its order number?
我需要以编程方式在它们的容器中重新排列我的 flex 项目,但我似乎无法找到如何通过 order
select 它们数字。问题是它们没有按 DOM 顺序显示,而是使用 order
css 属性显示。
How do I rearrange them?
我的html:
<div id="container">
<div style="order: 17"></div>
<div style="order: 25"></div>
<div style="order: 2"></div>
<div style="order: 3"></div>
// ...
</div>
基本上我需要这样做:
| A | B | C | D | E |
+----------->
<---+---+---+
result:
| A | C | D | E | B |
所以,我想到了一个稍微滥用 CSS3 选择器的想法,它似乎有效,但我想知道这是如何 合法 的。
document.querySelector('div[style*="order: 25;"]')
然后要交换两个项目,我需要这样做:
var t = document.querySelector('div[style*="order: 25;"]');
document.querySelector('div[style*="order: 26;"]').style.order = 25;
t.style.order = 26;
您可以根据计算的 order
.
对弹性项目进行排序
请注意,如果两个弹性项目具有相同的 order
,则应根据它们的 DOM 位置对其进行排序。也就是说,排序必须是稳定的。由于 [].sort
不一定稳定,我将使用 merge sort.
的自定义实现
var orderedChildren = mergeSort([].map.call(
document.getElementById('container').children,
function(child) {
return [child, +getComputedStyle(child).order];
}
)).map(function(pair) {
return pair[0];
});
function mergeSort(arr) {
var m = Math.floor(arr.length / 2);
if(!m) return arr;
var arr2 = mergeSort(arr.splice(m)),
arr1 = mergeSort(arr.splice(0));
while(arr1.length && arr2.length)
arr.push((arr1[0][1] > arr2[0][1] ? arr2 : arr1).shift());
return arr.concat(arr1, arr2);
}
var orderedChildren = mergeSort([].map.call(
document.getElementById('container').children,
function(child) {
return [child, +getComputedStyle(child).order];
}
)).map(function(pair) {
return pair[0];
});
function mergeSort(arr) {
var m = Math.floor(arr.length / 2);
if(!m) return arr;
var arr2 = mergeSort(arr.splice(m)),
arr1 = mergeSort(arr.splice(0));
while(arr1.length && arr2.length)
arr.push((arr1[0][1] > arr2[0][1] ? arr2 : arr1).shift());
return arr.concat(arr1, arr2);
}
for(var i=0; i<orderedChildren.length; ++i) {
orderedChildren[i].textContent = i;
}
#container {
display: flex;
flex-wrap: wrap;
}
#container > div {
border: 1px solid;
padding: 5px;
}
<div id="container">
<div style="order: 17"></div>
<div style="order: 25"></div>
<div style="order: 2"></div>
<div style="order: 3"></div>
<div style="order: 17"></div>
<div style=""></div>
<div style="order: -17"></div>
<div style="order: 2"></div>
</div>
If the numbers are ordered, it means JS has iterated the flex items according to their <code>order</code> property.
我需要以编程方式在它们的容器中重新排列我的 flex 项目,但我似乎无法找到如何通过 order
select 它们数字。问题是它们没有按 DOM 顺序显示,而是使用 order
css 属性显示。
How do I rearrange them?
我的html:
<div id="container">
<div style="order: 17"></div>
<div style="order: 25"></div>
<div style="order: 2"></div>
<div style="order: 3"></div>
// ...
</div>
基本上我需要这样做:
| A | B | C | D | E |
+----------->
<---+---+---+
result:
| A | C | D | E | B |
所以,我想到了一个稍微滥用 CSS3 选择器的想法,它似乎有效,但我想知道这是如何 合法 的。
document.querySelector('div[style*="order: 25;"]')
然后要交换两个项目,我需要这样做:
var t = document.querySelector('div[style*="order: 25;"]');
document.querySelector('div[style*="order: 26;"]').style.order = 25;
t.style.order = 26;
您可以根据计算的 order
.
请注意,如果两个弹性项目具有相同的 order
,则应根据它们的 DOM 位置对其进行排序。也就是说,排序必须是稳定的。由于 [].sort
不一定稳定,我将使用 merge sort.
var orderedChildren = mergeSort([].map.call(
document.getElementById('container').children,
function(child) {
return [child, +getComputedStyle(child).order];
}
)).map(function(pair) {
return pair[0];
});
function mergeSort(arr) {
var m = Math.floor(arr.length / 2);
if(!m) return arr;
var arr2 = mergeSort(arr.splice(m)),
arr1 = mergeSort(arr.splice(0));
while(arr1.length && arr2.length)
arr.push((arr1[0][1] > arr2[0][1] ? arr2 : arr1).shift());
return arr.concat(arr1, arr2);
}
var orderedChildren = mergeSort([].map.call(
document.getElementById('container').children,
function(child) {
return [child, +getComputedStyle(child).order];
}
)).map(function(pair) {
return pair[0];
});
function mergeSort(arr) {
var m = Math.floor(arr.length / 2);
if(!m) return arr;
var arr2 = mergeSort(arr.splice(m)),
arr1 = mergeSort(arr.splice(0));
while(arr1.length && arr2.length)
arr.push((arr1[0][1] > arr2[0][1] ? arr2 : arr1).shift());
return arr.concat(arr1, arr2);
}
for(var i=0; i<orderedChildren.length; ++i) {
orderedChildren[i].textContent = i;
}
#container {
display: flex;
flex-wrap: wrap;
}
#container > div {
border: 1px solid;
padding: 5px;
}
<div id="container">
<div style="order: 17"></div>
<div style="order: 25"></div>
<div style="order: 2"></div>
<div style="order: 3"></div>
<div style="order: 17"></div>
<div style=""></div>
<div style="order: -17"></div>
<div style="order: 2"></div>
</div>
If the numbers are ordered, it means JS has iterated the flex items according to their <code>order</code> property.