我有一个待办事项列表。每行都有一个可以点击的星形图标,就像gmail一样。这里的区别在于,如果您点击星号,它应该排在最前面(更高的优先级),但也可以通过升序alpha在星号组中重新排序。 Unstarred项目排序如下,也按升序alpha排序。除了alpha排序之外,一切都按预期工作。下面是我正在做的那个排序函数。我已经验证一切都在下面工作,除了 //按alpha位排序数组...
排序失败:
function sortTasks(currList) {
var starredTasks = [];
var unstarredTasks = [];
//create arrays
$('li.task').each(function(){
if ($(this).children('img.star').attr('src') == "images/star_checked.gif") {
starredTasks.push($(this));
} else {
unstarredTasks.push($(this));
}
});
//sort the arrays by alpha
starredTasks.sort( function(a,b){ ($(a).children('p.task-name').text().toUpperCase() > $(b).children('p.task-name').text().toUpperCase()) ? 1 : -1;});
unstarredTasks.sort( function(a,b){ ($(a).children('p.task-name').text().toUpperCase() > $(b).children('p.task-name').text().toUpperCase()) ? 1 : -1;});
//draw rows starred first, unstarred second
$(currList).empty();
for (i=0; i < starredTasks.length; i++) {
$(currList).append(starredTasks[i]);
}
for (i=0; i < unstarredTasks.length; i++) {
$(currList).append(unstarredTasks[i]);
}
}
此数组已按照最初绘制的顺序填充了任务行。数据渲染得很好,但基本上保持不变。
示例任务行:
<div id="task-container" class="container">
<form name="enter-task" method="post" action="">
<input id="new-task" name="new-task" type="text" autofocus>
</form>
<h2 id="today">today</h2>
<ul id="today-list">
<li id="457" class="task">
<img class="star" src="images/star_checked.gif">
<p class="task-name" contenteditable>buy milk</p>
<p class="task-date"> - Wednesday</p>
</li>
</ul>
<h2 id="tomorrow">tomorrow</h2>
<ul id="tomorrow-list">
</ul>
<h2 id="future">future</h2>
<ul id="future-list">
</ul>
<h2 id="whenever">whenever</h2>
<ul id="whenever-list">
</ul>
</div>
starredTasks数组中的每个项目都是整个任务行。我假设$(a)
与$(li)
的级别相同?
这是触发排序的函数:
$('body').on('click', 'img.star', function(){
var thisList = '#' + $(this).parent('li').parent('ul').attr('id');
if ($(this).attr('src') == 'images/star_checked.gif') {
$(this).attr('src', 'images/star_unchecked.gif');
} else {
$(this).attr('src', 'images/star_checked.gif');
}
sortTasks(thisList);
});
另外,我怀疑它值得一提,但数据存储在mySQL中并通过php预先填充。
我不确定如何直接在.sort()
上使用$('li')
而不将其拆分为单独的数组......
有人看到我的蠢事吗?
答案 0 :(得分:2)
我没有看到您将排序列表添加回DOM的位置。如果你不是,那就是问题所在。对元素数组进行排序根本不会更新DOM。
此外,您的分类非常昂贵。最好映射具有与实际值配对的元素的对象数组进行排序。
最后,您似乎在页面上多次使用相同的ID。那是错的。它可能适用于jQuery的.children(selector)
过滤器,但它仍然是错误的。你需要改变它。
这里我映射了一个对象数组,这些对象包含一个text
属性,其中包含要排序的文本和一个包含该元素的task
属性。
我将p#task-name
更改为p.task-name
,因此您应该将其更改为class="task-name"
元素。
然后我使用.localeCompare()
进行排序,返回一个数值。
最后,.forEach()
循环将元素附加到DOM。
var data = starredTasks.map(function(t) {
return { task: t,
text: $(t).children('p.task-name').text().toUpperCase()
};
}).sort(function(obj_a, obj_b) {
obj_a.text.localeCompare(obj_b.text);
}).forEach(function(obj) {
original_container.append(obj.task);
});
这假设starredTasks
是一个实际的数组。如果它是一个jQuery对象,那么执行starredTasks.toArray().map(func...
。
original_container
表示jQuery对象,它是task
元素的直接父对象。