[英]How can I insert new list items sorted by attribute value?
Let's imagine we have an HTML message list.假设我们有一个 HTML 消息列表。 Each item has index - Unix timestamp with milliseconds .
每个项目都有 index-Unix 时间戳,以毫秒为单位。
<ul>
<li ts="1657744925386">Item 1</li>
<li ts="1657744941061">Item 2</li>
<li ts="1657744953364">Item 3</li>
<li ts="1657744964372">Item 4</li>
<li ts="1657744973219">Item 5</li>
<li ts="1657744978450">Item 6</li>
</ul>
Then we have to insert another item, with ts= 1657744950123 .然后我们必须插入另一个项目, ts= 1657744950123 。 It should be after Item 3.
它应该在第 3 项之后。
Is there an efficient way to calculate the new position in the list so that jQuery can insert the new element (because it requires a reference element relative to which will be inserted after or before the new element), given that there can be a lot of messages on the page and we don't have possibility to walk through all of them every time, making comparisons?考虑到可能有很多页面上的消息,我们不可能每次都遍历所有消息,进行比较?
Assuming no existing data structure representing the list, I'd loop over the list elements, checking the attribute value, until I found the first larger value.假设没有表示列表的现有数据结构,我将遍历列表元素,检查属性值,直到找到第一个较大的值。 That's the index + 1 at which you'll insert.
那就是您要插入的索引 + 1。
If there is a data array, you could do something similar on the array itself and regenerate the list.如果有一个数据数组,您可以对数组本身执行类似的操作并重新生成列表。
Here's a wild 'n woolly example of the former approach.这是前一种方法的一个疯狂的例子。 If you need the text nodes to also be updated, you probably want to take approach #2 and rebuild the list programmatically.
如果您还需要更新文本节点,您可能需要采用方法 #2 并以编程方式重建列表。
const list = document.querySelector('ul'); const items = list.querySelectorAll('li'); const newItemVal = 1657744950123; let itemAfterIndex; for (const [index, item] of items.entries()) { const tsVal = parseInt(item.getAttribute('ts')); if (tsVal > newItemVal) { itemAfterIndex = index; break; } } const newItem = document.createElement('li'); newItem.setAttribute('ts', newItemVal); newItem.textContent = 'New item'; const itemAfter = list.querySelectorAll('li')[itemAfterIndex]; list.insertBefore(newItem, itemAfter);
<ul> <li ts="1657744925386">Item 1</li> <li ts="1657744941061">Item 2</li> <li ts="1657744953364">Item 3</li> <li ts="1657744964372">Item 4</li> <li ts="1657744973219">Item 5</li> <li ts="1657744978450">Item 6</li> </ul>
Consider the following jQuery example.考虑以下 jQuery 示例。
$(function() { var myNewItem = $("<li>", { ts: 1657744950123 }).html("Item 7"); $("ul li").each(function(i, el) { console.log($(el).attr("ts"), myNewItem.attr("ts")); if ($(el).attr("ts") > myNewItem.attr("ts")) { myNewItem.insertBefore(el); return false; } }); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <ul> <li ts="1657744925386">Item 1</li> <li ts="1657744941061">Item 2</li> <li ts="1657744953364">Item 3</li> <li ts="1657744964372">Item 4</li> <li ts="1657744973219">Item 5</li> <li ts="1657744978450">Item 6</li> </ul>
This assumes the list is already sorted.这假设列表已经排序。 If not, you can append the new item anyplace, detach all the items, sort them, and append them back.
如果没有,您可以在任何地方附加新项目,分离所有项目,对它们进行排序,然后将它们附加回来。
$(function() { $("<li>", { ts: 1657744950123 }).html("Item 7").appendTo("ul"); var myItems = $("ul li").detach(); myItems.sort(function(a, b) { if ($(a).attr("ts") < $(b).attr("ts")) { return -1; } if ($(a).attr("ts") > $(b).attr("ts")) { return 1; } if ($(a).attr("ts") == $(b).attr("ts")) { return 0; } }); $("ul").append(myItems); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <ul> <li ts="1657744925386">Item 1</li> <li ts="1657744941061">Item 2</li> <li ts="1657744953364">Item 3</li> <li ts="1657744964372">Item 4</li> <li ts="1657744973219">Item 5</li> <li ts="1657744978450">Item 6</li> </ul>
See more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort查看更多: https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.