【问题标题】:jQuery - sorting a list of items by class after they're displayedjQuery - 显示后按类对项目列表进行排序
【发布时间】:2014-07-16 10:56:21
【问题描述】:

我正在创建一个脚本,用于生成有关患者症状的报告。下面的列表是报告列表,它是在患者回答所有问题后最终生成的。我编写了一些代码,根据患者的回答将一个类添加到下面的列表中。可能的答案是“一点也不”、“一点点”、“很多”。 如果患者选择“根本没有”选项,则从该列表中删除项目。

如果患者为某个问题选择“一点点”,则下面列表中的相应项目将获得一个名为“moderate_risk”的类。如果他选择“很多”,那么一个项目将获得一个名为“high_risk”的类。

我想在应用类之后对这个列表进行排序,并首先放置“high_risk”项目,然后是“moderate_risk”项目。

如何使用 jQuery 做到这一点?

<ul class="summarylist" id="printableArea">
        <li>Difficultly in completing daily activities such as showering, toileting, dressing, and household 
        tasks, preparing meals</li>
        <li>Bothering symptoms such as breathlessness, coughing, pain, not sleeping, poor appetite, 
        constipation, fatigue, depression or anxiety</li>
        <li>More frequent hospitalisations</li>
        <li>Needing more information about their lung disease </li>
        <li>Needing more support for themselves and/or their carer </li>                    

</ul>

【问题讨论】:

  • 你可以使用排序功能来实现这个developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 那么,首先我必须将每个元素添加到数组中,然后从 summarylist 中删除所有内容,然后使用该函数对其进行排序,最后将数组中的内容添加到“summarylist”?跨度>
  • 选择所有要排序的元素 > 排序 > 将它们附加回父元素 - 附加将移动元素而不是克隆它们,因此无需先删除它们

标签: jquery html css list class


【解决方案1】:

我建议您执行I've demonstrated for you on jsFiddle here 之类的操作。 基本上,您可以使用 JavaScript Array 对象附带的 sort 函数,并提供您自己的比较函数,按顺序遍历这些 CSS 类,检查被比较的项目之一是否具有高优先级。 (当出现平局时,您可以调用另一个比较函数来添加另一个排序标准)。 jQuery 通过将您想要的 DOM 元素以数组的形式提供给您,从而为您提供了便利。对该数组进行排序后,您只需更新 DOM 以匹配。见Trent Richardson's Sort DOM Elements with jQuery article

jQuery(document).ready(function ($) {
    var priorityClassNames = ["high_risk", "moderate_risk", "low_risk"];
    var $list = $("ul#printableArea");

    // Simple comparison function that sorts by text content of the elements
    var sortByContents = function (a, b) {
        var aText = $(a).text();
        var bText = $(b).text();
        if (aText < bText)
            return -1;
        else if (aText > bText)
            return 1;
        else
            return 0;
    };

    // Comparison function that first sorts by priority class
    // then uses sortByContents function to break ties
    var sortByClassThenByContents = function (a, b) {
        var $a = $(a);
        var $b = $(b);
        var comparisonResult = 0;
        $.each(priorityClassNames, function() {
            var className = this;
            if ($a.hasClass(className) || $b.hasClass(className)) {
                // a comes first since it has class but b doesn't
                if ($a.hasClass(className) && !($b.hasClass(className)))
                    comparisonResult = -1; 
                // b comes first since it has class but a doesn't
                else if (!$a.hasClass(className) && ($b.hasClass(className)))
                    comparisonResult = 1; 
                // Both have same class -- sory by next criterion
                else {
                    comparisonResult = sortByContents(a, b);
                }
                return false; // break out of $.each
            }
        });
        console.log(comparisonResult, $a, $b);
        return comparisonResult;
    };

    // Randomly assign high/moderate/low classes for demonstration
    $("button#add-classes").on("click", function () {
        $list.children("li")
        .each(function () {
            var $item = $(this);
            // Remove any old priority classes
            $item.removeClass(priorityClassNames.join(" "));
            // Randomly pick a priority class
            var r = Math.floor(Math.random() * priorityClassNames.length);
            $item.addClass(priorityClassNames[r]);
        });
    });

    // Sort by high/moderate/low
    $("button#sort").on("click", function () {
        console.log("About to sort");
        $list.children("li")
        // Sort jQuery object with <li> elements
        .sort(sortByClassThenByContents)
        // Take them out of the DOM
        .detach()
        // Put them back (in order)
        .appendTo($list);
    });
});

【讨论】:

  • 很高兴它有帮助。在我写完之后我注意到,在某些情况下,行为可能与预期不同:如果不存在优先级,则不会对项目进行排序。如果这不是您想要的,您可以稍微修改sortByClassThenByContents 函数,以便比较结果默认为undefined(未设置为0),然后检查最后是否仍然是undefined,如果是,则按下一个标准排序。我更新了 jsFiddle 代码以包含它,但保留了这个答案,因为它真的取决于你想要什么,希望这个例子足够容易理解。
  • 如果现在有人遇到这个问题,我认为重要的是要指出 JavaScript (ECMAScript) 在我发布这个答案后的 3 年多时间里已经有了很大的发展。例如,Array.prototype.forEach 现在是标准的,使得 $.each 不再需要。一般来说,有人可能会争辩说jQuery 的相关性/必要性要低得多。最后,我想提一下,“将真相排除在 DOM 之外”被认为是一种很好的做法,但遗憾的是,这个解决方案没有这样做。
  • sortByClassThenByContents 函数重构为可组合的也是更好的做法,即有一个函数将两个单条件比较函数作为参数,并且本身充当比较函数。这将允许任意的分层排序,也便于测试。
【解决方案2】:

这对我有用。

<script type="text/javascript">
$(function() {
    sortByClass();
});

function sortByClass() {
    var lis = [];
    $('li').each(function(i, li) {
        var $li = $(li);
        lis.push([$li, $li.attr('class')]);
    });

    lis.sort(function(a, b) {
        return a[1] > b[1];
    });

    $('li').remove();
    $.each(lis, function(i, li) {
        $('ul').append(li[0]);
    });
}
</script>

<ul class="summarylist" id="printableArea">
    <li class="moderate_risk">Difficultly in completing daily activities such as showering, toileting, dressing, and household 
    tasks, preparing meals</li>
    <li class="high_risk">Bothering symptoms such as breathlessness, coughing, pain, not sleeping, poor appetite, 
    constipation, fatigue, depression or anxiety</li>
    <li class="moderate_risk">More frequent hospitalisations</li>
    <li class="moderate_risk">Needing more information about their lung disease </li>
    <li class="high_risk">Needing more support for themselves and/or their carer </li>                    
</ul>

【讨论】:

  • 感谢您回答这个问题,但第二个答案对我来说效果最好。
猜你喜欢
  • 1970-01-01
  • 2013-01-09
  • 2015-06-27
  • 1970-01-01
  • 2022-01-26
  • 2018-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多