Javascript自定义排序功能取决于用户输入

时间:2016-01-10 14:28:40

标签: javascript jquery sorting asynchronous user-input

我正在尝试为Javascript array.sort方法创建自定义比较回调函数。它应该根据用户输入返回一个值。

当调用该回调函数时,它应该等到用户单击按钮。根据单击的按钮,函数将知道两个元素中的哪一个更大并返回相应的结果(1或-1)。

我知道等待用户输入的唯一方法是使用事件监听器功能,但我不知道如何将其调整为我必须传递给array.sort()方法的自定义函数。 / p>

以下是我尝试的代码;我知道这段代码不会起作用:

var array=["a","b","c"];
array.sort(function(a,b){
    var result;

    $("#button1").click(function(){
        result = 1;
    });

    $("#button2").click(function(){
        result = -1;
    });
    return result;
}

我开始认为为此目的无法使用array.sort功能。

有办法做到这一点吗?

1 个答案:

答案 0 :(得分:0)

你可以通过使用window.confirm方法以丑陋的方式执行此操作,该方法具有等待进一步执行代码的行为,直到用户通过选择确定或取消来关闭弹出窗口:

array=["a","b","c"];
array.sort(function(a,b){
    var a_before_b = confirm("'" + a + "' will be sorted before '" + b 
                           + "'. Cancel to order differently.");
    return a_before_b ? -1 : 1;
});
document.body.innerHTML = '<p>Array sorted: ' + array + '</p>';
<p>You will get 2 to 3 pop up dialogs to sort [a, b, c]</p>

让用户通过正常交互回答,而不是通过模态对话框,仍然使用标准 sort 方法,这是一项艰巨的任务。

一个想法是保留给出的答案列表,并在每次有新答案时重复排序,通过 sort 回调函数提供这些答案。

一旦比较结果尚未给出答案,您就会将该比较呈现给用户,并以任何顺序完成其余的排序。排序的数组将被忽略,直到您获得所有比较的所有答案为止。

代码很长,主要是因为与页面的交互:

var array = ['a', 'b', 'c'];
var answers = [];
var questionTemplate = "Order '#' before or after '#'?"; 
var answerTemplate = "The array is sorted. Result: #."; 

function logMsg(msg) {
    $($('#log')[0].insertRow(-1).insertCell(-1)).text(msg);
}

function answer(order) {
    // keep track of answers
    answers.push(order);
    // show answers also in a log table
    logMsg($('#question').text() + ' - ' + (order<0? 'Before' : 'After'));
    askNext();
}

function askNext() {
    var arrayCopy = array.slice(0); // take real copy
    var questionNo = -1;
    arrayCopy.sort(function(a,b){
        questionNo++
        if (questionNo < answers.length) {
            // we already asked this, so use that answer
            return answers[questionNo];
        } 
        if (questionNo == answers.length) {
            // put question to user:
            $('#question').text(questionTemplate.replace('#', a).replace('#', b));
        }
        // don't care for now, just finish it. We need first to
        // get an answer, and will then restart the sort.
        return -1; 
    });
    if (array.length == answers.length) {
        // Array is now sorted according to answers:
        // Hide question section
        $('#questionDiv').hide(); 
        // Show the result
        logMsg(answerTemplate.replace('#', arrayCopy)); 
    }
}

function reset() {
    $('#array').text(array); 
    $('#questionDiv').show() 
    $('#log').html(''); // empty log table 
    answers = [];
    askNext();
}

// Set up click handlers
$('#reset').click(reset);
$('#before').click(answer.bind(null, -1));
$('#after').click(answer.bind(null,  1));
reset();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>The array <span id="array"></span> will be sorted by asking you questions:</p>
<table id="log"></table>
<div id="questionDiv">
    <p id="question" style="font-weight: bold"></p> 
    <button id="before">Before</button><button id="after">After</button>
</div>
<button id="reset">Restart</button>