Javascript根据属性值重新排序HTML元素



我有以下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>

一种方法是

  1. 迭代结果id并从dom获得相应的对象(结合您的最后。foreach轮删除d-done类)
  2. 获取所有已完成的元素并合并这两个列表
  3. 转换为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,因为我不需要只获得密钥,这使事情变得更加困难。

其次,按照多个过滤器重新组织所有内容的逻辑是:

  1. 排序/过滤所有
  2. 隐藏所有项目(使用d-none)
  3. 抓取所有的子包装器const wrapperItems = wrapper.children
  4. 创建一个名为wrapperNewItems的变量,用于保存新的排序/过滤项
  5. 创建一个变量保存ID (item-1, item-2等)已排序/过滤
  6. 将已排序的项目推入变量并删除d-none
  7. 将未排序的项推入变量并保留d-none

翻译成代码:

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;

相关内容

  • 没有找到相关文章

最新更新