我有以下HTML:
<div class="wrapper">
<div class="item" id="item-1">
</div>
<div class="item" id="item-2">
</div>
<div class="item" id="item-3">
</div>
</div>
在javascript中,我目前正在应用过滤器&对数组的结果进行排序:
results = Object.keys(list).filter(.....);
results = results.sort((a, b) => (....) ? 1 : -1);
// After the results have been filtered & sorted, hide all HTML elements:
document.querySelectorAll('.item').forEach(i => i.classList.add('d-none'));
// And then proceed to show only the results that have been filtered & sorted:
results.forEach(index =>
{
let id = list[index].id;
let item = document.getElementById('item-' + id);
item.classList.remove('d-none');
});
这个效果很好。问题是,现在我需要根据results
数组移动HTML元素,特别是id
字段。
A)期望输出: Array id [2,1]
<div class="wrapper">
<div class="item" id="item-2">
</div>
<div class="item" id="item-1">
</div>
<div class="item d-none" id="item-3">
</div>
</div>
B)期望输出: Array id [2]
<div class="wrapper">
<div class="item" id="item-2">
</div>
<div class="item d-none" id="item-1">
</div>
<div class="item d-none" id="item-3">
</div>
</div>
您可以使用prepend
函数将元素移动到顶部。
在下面的例子中,我只实现了关于移动元素的逻辑,并且我没有保护不存在的元素。你应该添加关于过滤等的逻辑,并保护可能的错误。
function sortDivs() {
let list = [2, 1];
let mainDiv = document.querySelectorAll('.wrapper')[0];
list.reverse().forEach(n => mainDiv.prepend(document.getElementById('item-'+n)));
}
.item {
border: black solid;
}
<div class="wrapper">
<div class="item" id="item-1">
item-1
</div>
<div class="item" id="item-2">
item-2
</div>
<div class="item" id="item-3">
item-3
</div>
</div>
<br>
<button onClick="sortDivs()"> sort DIVs</button>
一种方法是
- 迭代结果id并从dom获得相应的对象(结合您的最后。foreach轮删除d-done类)
- 获取所有已完成的元素并合并这两个列表
- 转换为html并重置包装器的innerHTML
let results = [2,1]
let wrapper = document.getElementById('wrapper-id')
wrapper.innerHTML = results.map(id => document.querySelector('#item-' + id))
.concat([...document.querySelectorAll('.d-none')])
.map(elem => elem.outerHTML)
.join('')
<div class="wrapper" id="wrapper-id">
<div class="item" id="item-1">
item-1
</div>
<div class="item" id="item-2">
item-2
</div>
<div class="item d-none" id="item-3">
item-3
</div>
</div>
已解决.
我有几个问题:
第一个不是使用Object.keys(results).filter
,我应该使用results.filter
,因为我不需要只获得密钥,这使事情变得更加困难。
其次,按照多个过滤器重新组织所有内容的逻辑是:
- 排序/过滤所有
- 隐藏所有项目(使用
d-none
) 抓取所有的子包装器 - 创建一个名为
wrapperNewItems
的变量,用于保存新的排序/过滤项 - 创建一个变量保存ID (item-1, item-2等)已排序/过滤
- 将已排序的项目推入变量并删除
d-none
- 将未排序的项推入变量并保留
d-none
const wrapperItems = wrapper.children
翻译成代码:
document.querySelectorAll('.item').forEach(i => i.classList.add('d-none'));
const wrapper = document.getElementsByClassName('wrapper')[0];
// Saves the existing children
const wrapperItems = wrapper.children;
// Holds the new items ordered perfectly
let wrapperNewItems = [];
// Holds names that were filtered (item-1, item-2, etc)
let listOfNamesFiltered = [];
// Shows only the items filtered
results.forEach(item =>
{
let name = 'item-' + item.id;
let el = document.getElementById(name);
el.classList.remove('d-none');
wrapperNewItems.push(el);
listOfNamesFiltered.push(name);
});
for (let i = 0; i < wrapperItems.length; i++)
{
let item = wrapperItems[i];
let name = item.id; // id="" already contains "item-{id}"
// If the name already exists in the list, we won't add it again
if (listOfNamesFiltered.includes(name))
continue;
wrapperNewItems.push(item);
}
// Clears the div
wrapper.innerHTML = '';
// Appends the items once again
for (let i = 0; i < wrapperNewItems.length; i++)
wrapper.innerHTML += wrapperNewItems[i].outerHTML;