【问题标题】:How to sort list by priority in JavaScript?如何在 JavaScript 中按优先级对列表进行排序?
【发布时间】:2017-03-06 19:33:28
【问题描述】:

如何按优先级对列表项进行排序?这是一个待办事项清单。用户可以输入一个项目,选择一个优先级,并添加到列表中。

这是我的 HTML 表单:

<input id="task" type="text"/>

<select id="priority">
    <option id="Normal">Normal</option> 
    <option id="Urgent">Urgent</option>
    <option id="Critical">Critical</option>
    <option id="If You Can">If You Can</option>
</select>

<button onclick="amitFunction()">Add</button>

<hr/>

<table>
    <tr>
        <th id="result"></th>
        <th id="priorit"></th>
    </tr>
<table>

这是我的 JS:

 function amitFunction() {    
    /* Define vars and values  */
    var lia = document.createElement("p");
    var lib = document.createElement("p");
    var item = document.getElementById('task').value;
    var pro = document.getElementById('priority').value;
    var pro_array = ['Urgent','Critical','Normal'];
    var item_list = document.createTextNode(item);
    var item_pro = document.createTextNode(pro);

    lia.appendChild(item_list);
    lib.appendChild(item_pro);

    /*  Check if text is less than 6 chars or more than 42 chars  */
    if (item.length<6) {
        alert('Your text must have a least 6 chars');
    } else if (item.length>42) {
        alert('Your text must have less than 42 chars');
    } else {
        document.getElementById("result").appendChild(lia);
        document.getElementById("priorit").appendChild(lib);
        document.getElementById('task').value='';
    }

    /*  Change text color base on priority  */
    if (pro==pro_array[0]) {
        $("p:last-child").css('color','red');
    }
    if (pro==pro_array[1]) {
        $("p:last-child").css('color','orange');
    }
    if (pro==pro_array[2]) {
        $("p:last-child").css('color','green');
    }

    /*  Delete text when user clicks on it  */
    $([lia,lib]).click(function(){
        $([lia,lib]).css('color','gray');
        $([lia,lib]).css("text-decoration", "line-through");
    });
}

我需要的是,当用户添加一个新项目时,它会按优先级排序。

  1. 第一:紧急
  2. 秒:严重
  3. 第三个:正常
  4. 第四:如果可以的话

用户添加的每个新项目都应该这样排序。我该怎么做?

这是the complete script (JSBin) 了解我需要什么。

【问题讨论】:

  • 您可以创建 4 个 div display : none; 并将它们按您需要的“排序”顺序放置,然后根据所选优先级将任务添加到它们...如果 div 保持其“排序”位置,则正在排序。
  • 我将实现自己的排序功能并将其应用于项目集合。有关更多信息,请参阅Mozilla Developer Network's page on Array.sort。您可以假设选项是字符串,并使用 switch 语句告诉 JavaScript 顺序是什么,或者使用整数值来使用自然数(这是更好的方法)。

标签: javascript jquery css html


【解决方案1】:

首先,我建议您在每次创建 TODO 任务时创建一个新的表行,但是我决定尽可能多地保留您的代码并实现您所要求的。我承认这不是最好的决定,并且可以进行很多优化,但是我保留它只是因为代码中可能有许多有趣的案例可能会教你一些新的东西。执行排序。我希望这会有所帮助:)

您的 html,保持原样:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>

</head>
<body>
    <script src="https://code.jquery.com/jquery-3.1.0.js"></script>

<input id="task" type="text"/>
<select id="priority">
 <option id="Normal">Normal</option> 
<option id="Urgent">Urgent</option>
<option id="Critical">Critical</option>
<option id="If You Can">If You Can</option>
 </select>

<button onclick="amitFunction()">Add</button>

<hr/>
<table>
  <tr>
    <th id="result"></th>
<th id="priorit"></th>
  </tr>
<table>
</body>
</html>

以及编辑后的JS代码:

//creating a global collection to hold your todo list in memory
var todo_list = [];

function amitFunction() {

        var item = document.getElementById('task').value;

        /*  Check if text is less than 6 chars or more than 42 chars 
            and return if validation is not passed */
        if(item.length<6){
             alert('Your text must have a least 6 chars');
             return;
        }else if(item.length>42){
            alert('Your text must have less than 42 chars');
            return; 
        }

        var pro = document.getElementById('priority').value;

        //keep this for colors
        var pro_array = ['Urgent','Critical','Normal'];

        //map string priorities to numeric values
        var priorities = 
            {
              'Urgent' : 0, 
              'Critical' : 1,
              'Normal' : 2,
              'If You Can' : 3
            }

        //push each new task in the todo list
        todo_list.push(
          {
            priority : pro,
            task : item
          }
        );

        //Now this here is perhaps the most important part,
        //this is where you sort your todo list based on the
        //mapped to numeric values priorities
        todo_list.sort(function (task1, task2) {
          return priorities[task1.priority] - priorities[task2.priority];
        });

        //clear the containers holding your list
        var resultNode = document.getElementById("result");

        while (resultNode.firstChild) {
          resultNode.removeChild(resultNode.firstChild);
        }

        var priorityNode = document.getElementById("priorit");

        while (priorityNode.firstChild) {
          priorityNode.removeChild(priorityNode.firstChild);
        }

        //recreate the DOM based on the todo_list collection
        for(var i =0; i < todo_list.length; i++)
          {
            var lia = document.createElement("p");
            var lib = document.createElement("p");

            var item_list = document.createTextNode(todo_list[i].task);
            var item_pro = document.createTextNode(todo_list[i].priority);

            lia.appendChild(item_list);
            lib.appendChild(item_pro);

            document.getElementById("result").appendChild(lia);
            document.getElementById("priorit").appendChild(lib);
            document.getElementById('task').value='';

              /*  Change text color base on priority  */
            if(todo_list[i].priority == pro_array[0]){
                 $("p:last-child").css('color','red');
               }
            if(todo_list[i].priority == pro_array[1]){
                 $("p:last-child").css('color','orange');
               }
             if(todo_list[i].priority == pro_array[2]){
                 $("p:last-child").css('color','green');
               }

         }

         //reinitialize the click handlers
         var resultNode = document.getElementById("result");
         var priorityNode = document.getElementById("priorit");

        for(var i =0; i< resultNode.childNodes.length; i++) (function(i){ 
          resultNode.childNodes[i].onclick = function() {
            $([resultNode.childNodes[i],priorityNode.childNodes[i]]).css('color','gray');
            $([resultNode.childNodes[i],priorityNode.childNodes[i]]).css("text-decoration", "line-through");
          }
          priorityNode.childNodes[i].onclick = function() {
            $([resultNode.childNodes[i],priorityNode.childNodes[i]]).css('color','gray');
            $([resultNode.childNodes[i],priorityNode.childNodes[i]]).css("text-decoration", "line-through");
          }
        })(i);

  }

这里有一个工作示例:

https://jsbin.com/kudipacexi/edit?html,js,output

事实上有很多方法,另一种方法是不为您的列表保留全局集合,而是直接使用 DOM 元素进行排序,但是您仍然必须保留某种数字表示您的优先级以便按优先级对它们进行排序。将每个元素订阅到单击处理函数,然后根据函数的调用者添加 line-through 样式也可能是一个好主意。我建议的另一件事是,如果您使用 jQuery 而不是只关注 Vanilla JS,请尝试使用 jQuery 进行大部分 DOM 操作。

【讨论】:

  • ++ 用于增强学习过程和重构而不是重做。
【解决方案2】:

因为您有一个表格,我建议将其用作输出。

您可以重新排列您的选择,以便为每个选项添加优先级编号和颜色属性,例如:

<option value="2" color="green">Normal</option>

表格可以包含第一列作为当前行的优先级。此列将被隐藏。

每次必须添加新行时,都会对表行执行排序过程。

sn-p:

$('button').on('click', function (e) {
    var priorityValue = $('#priority option:selected').val();
    var priorityText = $('#priority option:selected').text();
    var colorVal = $('#priority option:selected').attr('color');
    var taskValue = $('#task').val();
    if (taskValue.length < 6) {
        $('#errMsg').text('Your text must have a least 6 chars');
        return;
    } else if (taskValue.length > 42) {
        $('#errMsg').text('Your text must have less than 42 chars');
        return;
    }
    $('#errMsg').text('');

    //
    // create the new table row...
    //
    var newRow = $('<tr/>', {style: 'color:' + colorVal})
            .append($('<td/>', {style: "display: none", text: priorityValue}))
            .append($('<td/>', {text: taskValue}))
            .append($('<td/>', {text: priorityText}));


    //
    // enlarge current table rows with the current one and sort elements
    //
    var tableRowsSorted = $('#result tbody').append(newRow).find('tr').get().sort(function(a, b) {
        var p1 = +$(a).find('td:first').text();
        var p2 = +$(b).find('td:first').text();
        return p1 - p2;
    });

    //
    // append/replace the taable body
    //
    $('#result tbody').append(tableRowsSorted);

    //
    // reset input text
    //
    $('#task').val('');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>



<input id="task" type="text"/><span id="errMsg" style="color: red;"></span>
<select id="priority">
    <option value="2" color="green">Normal</option>
    <option value="0" color="red">Urgent</option>
    <option value="1" color="orange">Critical</option>
    <option value="3" color="black">If You Can</option>
</select>

<button>Add</button>

<hr/>
<table id="result">
    <thead>
    <tr>
        <th style="display: none">priority</th>
        <th>result</th>
        <th>priority</th>
    </tr>
    </thead>
    <tbody>

    </tbody>
</table>

【讨论】:

    猜你喜欢
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2019-10-04
    • 2012-06-07
    • 1970-01-01
    相关资源
    最近更新 更多