我已经基于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('')};
});
});
但我有些东西说必须有一个更优雅的答案?
答案 0 :(得分:1)
问题是vA
和vB
可能导致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;
});