I have a TODO list app with an Unordered list. Within it I have a few list items. The li classes are high,medium,low. I would like li's with the class high to be placed before li's with the class medium and last ones with low.
<ul id="tasks">
<li id="item3" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item3')"></a><span>This is a low priority task</span></li>
<li id="item4" class="priority high"><></span><a href="#" class="closex" onclick="removeItem('item4')"></a><span>This is a high priority task</span></li>
<li id="item5" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item5')"></a><span>This is another Low</span></li>
<li id="item7" class="priority medium"><span></span><a href="#" class="closex" onclick="removeItem('item7')"></a><span>And now a Medium</span></li>
</ul>
So the li with id of item4 should be first and then it should be item7 and then the li's with class low after.
I have a TODO list app with an Unordered list. Within it I have a few list items. The li classes are high,medium,low. I would like li's with the class high to be placed before li's with the class medium and last ones with low.
<ul id="tasks">
<li id="item3" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item3')"></a><span>This is a low priority task</span></li>
<li id="item4" class="priority high"><></span><a href="#" class="closex" onclick="removeItem('item4')"></a><span>This is a high priority task</span></li>
<li id="item5" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item5')"></a><span>This is another Low</span></li>
<li id="item7" class="priority medium"><span></span><a href="#" class="closex" onclick="removeItem('item7')"></a><span>And now a Medium</span></li>
</ul>
So the li with id of item4 should be first and then it should be item7 and then the li's with class low after.
Share Improve this question asked Nov 1, 2012 at 23:48 BryBry 656 bronze badges 12- Is php an option? Because then it would be real easy.. – Maxim VA Commented Nov 1, 2012 at 23:49
- 3 Why they are generated unordered at first place? Like, where it es from? db? file? hardcoded html? – deb0rian Commented Nov 1, 2012 at 23:51
- Someone had a similar question here stackoverflow./questions/5076844/… – Darren Wainwright Commented Nov 1, 2012 at 23:52
- 6 jQuery solution: jsfiddle/eAnJm (5 lines of code) – Šime Vidas Commented Nov 1, 2012 at 23:58
- 1 @user1792879 The API provided by a library like jQuery is far superior to the native browser API. A library also takes care of cross-browser inpatibilities. For learning purposes, you're wele to experiment with pure JS, but when writing actual web-apps, I strongly remend a library. – Šime Vidas Commented Nov 2, 2012 at 1:18
6 Answers
Reset to default 3Here's a pure JS version of @ŠimeVidas jQuery solution.
var tasks = document.querySelector('#tasks'),
items = document.querySelectorAll('#tasks > li');
for (var i = 0, arr = ['high', 'medium', 'low']; i < arr.length; i++) {
for (var j = 0; j < items.length; j++) {
if (~(" " + items[j].className + " ").indexOf(" " + arr[i] + " "))
tasks.appendChild(items[j]);
}
}
Assuming you can use jQuery, and assuming your list is not very big, and assuming you've only got these three fixed types with no plans on changing this, I'd probably just dump the whole set into memory, clear out the list, then put them back in the list in order. Something like:
jQuery(document).ready(function() {
var i;
var items = jQuery("#tasks li");
var lowItems = [];
var medItems = [];
var highItems = [];
for (i = 0; i < items.length; ++i) {
var jqItem = jQuery(items[i]);
if (jqItem.hasClass("low")) lowItems.push(jqItem);
if (jqItem.hasClass("medium")) medItems.push(jqItem);
if (jqItem.hasClass("high")) highItems.push(jqItem);
}
var tasks = jQuery("#tasks");
tasks.html("");
for (i = 0; i < highItems.length; ++i) {
tasks.append(highItems[i]);
}
for (i = 0; i < medItems.length; ++i) {
tasks.append(medItems[i]);
}
for (i = 0; i < lowItems.length; ++i) {
tasks.append(lowItems[i]);
}
});
Try this:
$(function(){
var sorter = [],
tasks = $('#tasks');
$('li.priority').each(function(){
var $this = $(this),
priority = $this.hasClass('high') ? 3 : ($this.hasClass('medium') ? 2 : 1);
sorter.push({
el : this,
priority : priority
});
}).detach();
sorter.sort(function(a, b){
return a.priority - b.priority;
});
$.each(sorter, function(){
tasks.append(this.el);
});
});
With no jquery:
<ul id="tasks">
<li id="item3" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item3')"></a><span>This is a low priority task</span></li>
<li id="item4" class="priority high"><></span><a href="#" class="closex" onclick="removeItem('item4')"></a><span>This is a high priority task</span></li>
<li id="item5" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item5')"></a><span>This is another Low</span></li>
<li id="item7" class="priority medium"><span></span><a href="#" class="closex" onclick="removeItem('item7')"></a><span>And now a Medium</span></li>
</ul>
<script type="text/javascript">
var tasks = document.getElementById("tasks");
var liElements = tasks.getElementsByTagName("li");
var lowPriority = [];
var mediumPriority = [];
var highPriority = [];
var removal = [];
for (var i = 0, len = liElements.length; i < len; i++) {
if (liElements[i].getAttribute("class").indexOf("low") > -1) lowPriority.push(liElements[i].cloneNode(true));
if (liElements[i].getAttribute("class").indexOf("medium") > -1) mediumPriority.push(liElements[i].cloneNode(true));
if (liElements[i].getAttribute("class").indexOf("high") > -1) highPriority.push(liElements[i].cloneNode(true));
removal.push(liElements[i]);
}
for (var i = 0, len = removal.length; i < len; i++ ) {
var liItem = removal[i];
liItem.parentNode.removeChild(liItem);
}
for( var i = 0, len = lowPriority.length; i < len; i++){
tasks.appendChild(lowPriority[i]);
}
for (var i = 0, len = mediumPriority.length; i < len; i++) {
tasks.appendChild(mediumPriority[i]);
}
for (var i = 0, len = highPriority.length; i < len; i++) {
tasks.appendChild(highPriority[i]);
}
</script>
Here's another jQuery–less option:
// Just a helper
function toArray(obj) {
var result = [];
for (var i=0, iLen=obj.length; i<iLen; i++) {
result[i] = obj[i];
}
return result;
}
// Uses querySelectorAll, but could use getElementsByTagName instead
function sortByPriority(id) {
var nodes;
var el = document.getElementById(id);
if (el) {
nodes = toArray(el.querySelectorAll('li.priority'));
nodes.sort(function(a, b) {
function getIndex(el) {
return el.className.indexOf('low') != -1? 1 :
el.className.indexOf('medium') != -1? 2 :
el.className.indexOf('high') != -1? 3 :
0; // default
}
return getIndex(b) - getIndex(a);
});
for (var i=0, iLen=nodes.length; i<iLen; i++) {
el.appendChild(nodes[i]);
}
}
}
It uses a few more lines that a jQuery (or perhaps any library) based solution but you don't have to load several thousand lines of library either.
Also, this runs about 5 times faster in Firefox and IE 9 and 10 times faster in Chrome than a jQuery solution (see http://jsperf./sortelementlist).
With pure JavaScript, and simple code!
var tasks = document.getElementById("tasks");
var lis = tasks.getElementsByTagName("li");
var lisarr = Array.prototype.slice.call(lis);
var priority = function(e){
var prio = {low: 0, medium: 1, high: 2};
return prio[e.getAttribute("class").match(/low|high|medium/)[0]];
};
lisarr.sort(function(a,b){
var ap = priority(a), bp = priority(b);
return bp - ap;
});
tasks.innerHTML = lisarr.reduce(function(prev, current){
return prev + current.outerHTML;
}, '');
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745131607a4612999.html
评论列表(0条)