繁体   English   中英

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

[英]Javascript reorder HTML element based on attribute value

我有以下 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) 预期输出:数组 ids [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) 预期输出:数组 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>

一种方法是

  1. 迭代结果 id 并从 dom 中获取相应的对象
  2. 获取所有 d-done 元素并组合两个列表
  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>

您可以使用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>

解决了

我有几个问题:

第一个是而不是使用Object.keys(results).filter我应该使用results.filter ,因为我不需要只获取键,这让事情变得更难。

其次,根据多个过滤器重新组织所有内容的应用逻辑是:

  1. 排序/过滤所有内容
  2. 隐藏所有项目(使用d-none
  3. 获取所有包装器子项const wrapperItems = wrapper.children
  4. 创建一个名为wrapperNewItems的变量,用于保存新的排序/过滤项目
  5. 创建一个变量来保存哪些 ID(项目 1、项目 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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM