【问题标题】:Split jQuery list into two alphabetically ordered parts by class按类将 jQuery 列表拆分为两个按字母顺序排列的部分
【发布时间】:2019-06-11 11:15:29
【问题描述】:

我希望将具有“活动”类的列表元素按字母顺序排列在列表顶部,列表的其余部分在下面单独排序。换句话说,

<li><label><span>zz</span></label></li>
<li class='active'><label><span>rr</span></label></li>
<li class='active'><label><span>bb</span></label></li>
<li><label><span>hh</span></label></li>
<li><label><span>ii</span></label></li>
<li class='active'><label><span>yy</span></label></li>
<li><label><span>kk</span></label></li>
<li><label><span>mm</span></label></li>

导致..

bb
rr
yy
hh
ii
kk
mm
zz

我认为我有正确的方法,但我似乎无法让它发挥作用。我认为与附加有关。任何人都可以帮助我克服最后的障碍吗? https://jsfiddle.net/Lcz47b9y/

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="rootUl">
    <li><label><span>zz</span></label></li>
    <li class='active'><label><span>rr</span></label></li>
    <li class='active'><label><span>bb</span></label></li>
    <li><label><span>hh</span></label></li>
    <li><label><span>ii</span></label></li>
    <li class='active'><label><span>yy</span></label></li>
    <li><label><span>kk</span></label></li>
    <li><label><span>mm</span></label></li>
</ul>

.

var myli = $('#rootUl li.active label').children('span').detach().sort(sortByText);

$('#rootUl').append($(myli))

function sortByText(a, b) {
    var first = $.trim($(a).text());
    var second = $.trim($(b).text());
    return first.localeCompare(second);
}

【问题讨论】:

标签: jquery list unordered


【解决方案1】:

要实现这一点,您可以修改 sort() 逻辑以首先比较元素上的类,然后如果它们匹配,则通过文本比较它们。试试这个:

$('#rootUl li').sort(function(a, b) {
  var $a = $(a), $b = $(b);
  if ($a.hasClass('active') && !$b.hasClass('active')) {
    return -1;
  } else if (!$a.hasClass('active') && $b.hasClass('active')) {
    return 1;
  }
  
  return $a.text().toUpperCase().localeCompare($b.text().toUpperCase());
}).appendTo('#rootUl');
.active { color: #C00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="rootUl">
  <li><label><span>zz</span></label></li>
  <li class='active'><label><span>rr</span></label></li>
  <li class='active'><label><span>bb</span></label></li>
  <li><label><span>hh</span></label></li>
  <li><label><span>ii</span></label></li>
  <li class='active'><label><span>yy</span></label></li>
  <li><label><span>kk</span></label></li>
  <li><label><span>mm</span></label></li>
</ul>

【讨论】:

  • 啊,现在我知道我哪里出错了。很好的解决方案。
  • 很高兴为您提供帮助。请注意,sort() 的逻辑可以不那么冗长,但它会变得更难理解,所以我把它留清楚了
【解决方案2】:

分离lis,而不是它们内部的&lt;span&gt;s - 然后,在.sort 函数中,访问跨度文本,然后使用prependTo 在顶部插入。

您似乎想要同时.actives 和非.actives 进行排序,所以也将这个逻辑放入您的比较函数中,减去hasClass 的调用:

const getSpanText = elm => $(elm).find('span').text();

$('#rootUl li')
  .detach()
  .sort(sortByText)
  .prependTo('#rootUl');

function sortByText(a, b) {
  return $(b).hasClass('active') - $(a).hasClass('active')
    || getSpanText(a).localeCompare(getSpanText(b));
}
.active {
  background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="rootUl">
  <li><label><span>zz</span></label></li>
  <li class='active'><label><span>rr</span></label></li>
  <li class='active'><label><span>bb</span></label></li>
  <li><label><span>hh</span></label></li>
  <li><label><span>ii</span></label></li>
  <li class='active'><label><span>yy</span></label></li>
  <li><label><span>kk</span></label></li>
  <li><label><span>mm</span></label></li>
</ul>

【讨论】:

  • 注意非.active元素也需要排序
  • 感谢@CertainPerformance,是的,这也有效,尽管 Rory 的解决方案是第一个完全有效的解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-09-04
  • 1970-01-01
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-15
相关资源
最近更新 更多