开发者

Sorting in the DOM with adjacent elements

开发者 https://www.devze.com 2023-02-19 02:33 出处:网络
I have the the following DOM structure which I want to sort according to the data-created attribute. <a id=\"comment-34\" href=\"#\"/>

I have the the following DOM structure which I want to sort according to the data-created attribute.

<a id="comment-34" href="#"/>
<li data-created="12342342" />

<a id="comment-35" href="#"/>
<li data-created="89342342" />

<a id="comment-36" href="#"/> 
&l开发者_JAVA技巧t;li data-created="45363342" />

I CANNOT (for various reasons) wrap the <a> and <li> in an outer <div>. I want to do javascript sorting. All the jQuery sorting plugins can do the sorting if I just had the <li>. E.g. using the tinysort jQuery plugin ( http://tinysort.sjeiti.com/ ) I can do

$('li').tsort({order:'desc', attr:'data-created'});

However what happens after the sort is that <a> are no longer associated with their original siblings. I also evaluated https://github.com/jamespadolsey/jQuery-Plugins/tree/master/sortElements/ but it may suffer from the same problem.

Any way to do this? Again, I cannot wrap the <a> and <li> in an outer <div>. I also don't want to dynamically wrap a <div> so that I can use tsort.

Any clean solutions :-) ?


Something like this should work for you:

var elms = [];
$('a').each(function() { //create the array of a and li
    var pair = {
        aTag: $(this),
        liTag: $(this).next("li")
    };
    elms.push(pair);
});
$("a, li").detach(); //detach them from the dom
elms.sort(function(a, b) {
    return a.liTag.data("created") < b.liTag.data("created"); //sort based upon the created data
});

$.each(elms , function(){
    $("ul").append(this.aTag).append(this.liTag); //push them back to the dom.
});

Code example on jsfiddle.


You can't really have <li> and <a> elements as siblings in the first place. A list item must be inside a list (<ol>,<ul>), where other elements are not allowed.

Ignoring that, you can simply grab each pair, remove from the DOM, reorder, then put them back. It's quite straight-forward. Example:

var items = [];
$('#sortme a').each(function(){

  // grab the element and its next sibling
  var self = $(this)
    , next = self.next('div');

  items.push([
    self.remove().get(0),
    next.remove().get(0)
  ]);
});

items.sort(function(a,b){
  return a[1].getAttribute('data-created') > b[1].getAttribute('data-created');
});

$.each(items, function(){
  $('#sortme').append(this[0], this[1]);
});

Test here: http://jsbin.com/okajo4/edit

Edit: a simpler version :)

var sorted = $('#sortme');

sorted.find('div')
  .sort(function(a,b){
    return $(a).data('created') > $(b).data('created');
  })
  .each(function(){
    $(this).prev('a').andSelf().appendTo(sorted);
  });


Move the a elements inside their respective list items. Then you ought to be able to use the sort you mentioned.

Even if having the elements as siblings is valid, it still strikes me as bad form.

0

精彩评论

暂无评论...
验证码 换一张
取 消