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

  显示原文与译文双语对照的内容

Jquery中创建了一个非常简单的greasemonkey脚本- sort按子children的div innerHTML排序to在上添加按钮,使之按日期排序,并按比例排序。 除了在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 http://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 看到一个示例页面,它包含 block 来排序类似于


<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,并且它还有利于在排序顺序中使用。 但是我在想是否还有更优雅的方法?

Edit: 替换 $("#scalesort" ).click(function() {.. . 具有以下代码的block 执行了以下操作


$("#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('')};
 });

});

但我觉得应该有更优雅的答案?

时间: 作者:

问题是 vAvB 可以要么要么要么两者都会导致 NaN 。 我没有找到任何'<'或者'>'语句与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;
});

作者:
...