将html内容转换为整数然后在jquery中排序的问题

时间:2014-01-15 20:20:23

标签: jquery sorting greasemonkey

我已经基于Jquery - sort DIV's by innerHTML of children创建了一个非常简单的greasemonkey脚本,可以在www.oldmapsonline.org的结果面板上添加按钮,以便按日期和按比例进行排序。这似乎工作正常,除了在html中没有缩放的记录上进行缩放排序。

// ==UserScript==
// @name       Sort oldmapsonline.org records
// @namespace  http://www.whatsthatpicture.com/
// @version    0.1
// @description  A simple tool to add a sort option (by date and by scale)
// @match      http://www.oldmapsonline.org/*
// @copyright  2014, James Morley @jamesinealing
// @require    http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js

// ==/UserScript==

// create html buttons and insert in place of search header text
var links = 'Sort: <a href="#" id="datesort">Date</a> <a href="#" id="scalesort">Scale</a>';
$( "#instant-search-header" ).html( links );

//add two event handlers for the sort buttons
$( "#scalesort" ).click(function() {
    sortUsingNestedText($('#sidecanvas'), "div", "span.mapscale");
});
$( "#datesort" ).click(function() {
    sortUsingNestedText($('#sidecanvas'), "div", "span.year");
});

// sorting function adapted from https://stackoverflow.com/questions/7831712/jquery-sort-divs-by-innerhtml-of-children
function sortUsingNestedText(parent, childSelector, keySelector) {
  var items = parent.children(childSelector).sort(function(a, b) {
    var vA = parseInt($(keySelector, a).text().replace('1:','').replace(' ','')); // the replace actions removes spaces and the '1:' in the scale, parsInt makes sure it's a number
    var vB = parseInt($(keySelector, b).text().replace('1:','').replace(' ',''));
    return (vA < vB) ? -1 : (vA > vB) ? 1 : 0;
  });
parent.append(items);
};

您可以在http://www.oldmapsonline.org/#bbox=169.619637,-46.121916,171.816902,-44.130108&q=&datefrom=1730&dateto=1750看到一个示例页面,其中包含用于对此类进行排序的块

<div id="sidecanvas" class="content" style="-webkit-user-select: none;">
  <div class="item clearFix" id="4638.003"><img src="/img/75/rumsey/4638.003.jpg">
    <div class="info">
      <h2 class="title"><span class="editions"></span><span class="maintitle">L'Hemisphere Meridional.</span></h2>
      <p class="details"><span class="mapscale"> 1:37 000 000</span><span class="author"><span class="year">1742</span> - Lisle, Guillaume de, 1675-1726</span></p>
    </div>
  </div>
  <div class="item ...
  ...
  </div>
</div>

对于没有比例的记录,html是<span class="mapscale"></span>,这似乎阻止它正确排序(即使它没有引发任何错误)。

如果所有条目都有比例(例如http://www.oldmapsonline.org/#bbox=150.326271,-28.645704,153.9188,-26.336192&q=&datefrom=1825&dateto=1825),它似乎可以正常工作。

我有什么想法可以允许这个吗?我想首先迭代这些值并将空值设置为9999999999会起作用,并且还可以确保它们在排序顺序中排在最后。但我想知道是否有更优雅的东西?

修改 用以下代码替换$( "#scalesort" ).click(function() { ...块做了诀窍

$( "#scalesort" ).click(function() { 
    // first we check for items with no scale set, and set a very high number to make sure they get sorted last
    $('.mapscale').each(function(index) {
        var scale = $( this ).text();
        if (scale == '') { $( this ).text('9999999999')};
    });
    //then we call the sort function
    sortUsingNestedText($('#sidecanvas'), "div", "span.mapscale");
    //then we scrub the high values so they don't get displayed
    $('.mapscale').each(function(index) {
        var scale = $( this ).text();
        if (scale == '9999999999') { $( this ).text('')};
    });

});

但我有些东西说必须有一个更优雅的答案?

1 个答案:

答案 0 :(得分:1)

问题是vAvB可能导致NaN或两者都导致NaN。我还没找到任何'&lt;'或'&gt;'声明与NaN的比较返回true。 (MDN说,“NaN不等于任何东西,包括NaN”。)

您只需使用您发布的解决方案中使用的高值替换NaN,或者使用NaN值创建更具创意的内容。

function sortUsingNestedText(parent, childSelector, keySelector) {
  var items = parent.children(childSelector).sort(function(a, b) {
    var vA = parseInt($(keySelector, a).text().replace('1:','').replace(' ','')); // the   replace actions removes spaces and the '1:' in the scale, parsInt makes sure it's a number
    var vB = parseInt($(keySelector, b).text().replace('1:','').replace(' ',''));
    if (isNaN(vA)) { vA = 9999999999; }
    if (isNaN(vB)) { vB = 9999999999; }
    return (vA < vB) ? -1 : (vA > vB) ? 1 : 0;
});

也许是这样的:

function sortUsingNestedText(parent, childSelector, keySelector) {
  var items = parent.children(childSelector).sort(function(a, b) {
    var vA = parseInt($(keySelector, a).text().replace('1:','').replace(' ','')); // the   replace actions removes spaces and the '1:' in the scale, parsInt makes sure it's a number
    var vB = parseInt($(keySelector, b).text().replace('1:','').replace(' ',''));
    if (isNaN(vA) && !isNaN(vB)) { return 1; }
    if (isNaN(vB) && !isNaN(vA)) { return -1; }
    if (isNaN(vA) && isNaN(vB)) { return 0; }
    return (vA < vB) ? -1 : (vA > vB) ? 1 : 0;
});