我加载了您的脚本,添加了时间线,并对其进行了测试。从 AJAX 完成到表格被修复并完成所用的时间只有 400 到 500 毫秒!对于大多数人和情况来说,这已经足够快了。
但是,对于那些你绝对想挤出毫秒的时间,你可以切换到MutationObservers。这些是挑剔、脆弱且跨浏览器可移植性较差,但速度很快。
在这种情况下,MutationObservers 将 AJAX 到固定表的时间缩短到 20 到 40 毫秒的范围内。
我建议使用像 Mutation Summary 这样的库来减轻过程中的一些痛苦。
从简单 waitForKeyElements() 实现转换为 Mutation Summary:
-
添加
@require https://raw.githubusercontent.com/rafaelw/mutation-summary/master/src/mutation-summary.js
到您的元数据块。
-
将您的 waitForKeyElements 回调和 simple 选择器插入此结构:
var muteObserver = new MutationSummary ( {
callback: handleDiscographyChanges,
rootNode: $( {ANY-JQUERY-SELECTOR} )[0],
queries: [ {element: {A-SIMPLE-SELECTOR}} ]
} );
function handleDiscographyChanges (muteSummaries) {
var mSummary = muteSummaries[0];
if (mSummary.added.length) {
{YOUR-CALLBACK} ( $(mSummary.added[0]) );
}
}
例如在这种情况下,更改:
waitForKeyElements (".display.discog", appendColumn);
收件人:
var muteObserver = new MutationSummary ( {
callback: handleDiscographyChanges,
rootNode: $("#band_disco")[0],
queries: [ {element: ".discog"} ]
} );
function handleDiscographyChanges (muteSummaries) {
var mSummary = muteSummaries[0];
if (mSummary.added.length) {
appendColumn ( $(mSummary.added[0]) );
}
}
rootNode 的位置是通过检查页面结构来确定的。
作为参考,具有 3 种可选方法和计时记录的完整脚本如下。它仅在 Firefox 上进行了测试,但应该也可以与 Tampermonkey 一起使用(也许)。
查看每行正上方的//OPTION n 行可选择注释掉。
// ==UserScript==
// @name Metal Archives (discography pages) - Reviews column split and sortable tables
// @include http://www.metal-archives.com/bands/*
// @include http://www.metal-archives.com/band/*
// @grant none
// @require http://code.jquery.com/ui/1.9.1/jquery-ui.min.js
// @require https://greasyfork.org/scripts/2199-waitforkeyelements/code/waitForKeyElements.js?version=6349
// @require https://greasyfork.org/scripts/5844-tablesorter/code/TableSorter.js?version=21758
// @require https://raw.githubusercontent.com/rafaelw/mutation-summary/master/src/mutation-summary.js
// ==/UserScript==
function appendColumn(jNode) {
logTime ("Table fixed");
// STEP 1+2: SPLIT THE 'REVIEWS' COLUMN INTO A 'REVIEWS' COLUMN AND A 'RATINGS' COLUMN
var tbl = jNode[0]; // table reference
// If the current sub-table has no data, then stop the execution of the function
if (tbl.rows[1].cells[0].innerHTML == '<em>Nothing entered yet. Please add the releases, if applicable. </em>') {
return;
}
var newCell, newText;
const cols = tbl.rows[0].cells.length - 1;
var tr = tbl.tHead.children[0],
th = document.createElement('th');
th.innerHTML = "Ratings";
th.className = "ratingsCol";
tr.appendChild(th);
for (i = 1; i < tbl.rows.length; i++) {
k = tbl.rows[i].cells[cols].innerHTML; // Retrieve the content of the current cell of the Review column and store it to variable k
re1 = /<a [^>]*>[^(]*[(]([^)]+)/ ; // (RegEx which matches the 'Ratings' percentage(incl.the % symbol)
l = re1.exec(k); // (Execute the RegEx and store it to variable l)
newCell = tbl.rows[i].insertCell(-1); // Add a new cell (for the new 'Ratings' column ) -for each row-
if (re1.test(k) != 0){ // If the RegEx has matches, (only) then create new cells with...
re0 = /(<a [^>]*>)[0-9]*[^(]/ ; // (RegEx which matches the reviews URL)
url = re0.exec(k); // (Execute the RegEx and store it to variable url)
newCell.innerHTML = url[1] + l[1] + '</url>'; // ...the Ratings percentage (which is also a link to the Reviews)...
re2 = /<a [^>]*>([0-9]*)[^(]/ ; // (RegEx which matches the 'Reviews' number)
m = re2.exec(k); // (Execute the RegEx and store it to variable m)
newCell = tbl.rows[i].cells[cols]; //
newCell.innerHTML = url[1] + m[1] + '</url>'; // ...and the Reviews number (which is also a link to the Reviews)
}
}
// STEP 3: MAKE THE DISCOGRAPHY TABLE SORTABLE (using the jQuery plugin "tablesorter")
$(tbl).tablesorter ( {
cssAsc: 'up',
cssDesc: 'down',
headers: {
0: {sorter: false}
}
} );
}
//OPTION 1
//waitForKeyElements (".display.discog", appendColumn);
$(document).ajaxComplete (function (e, xhr, config){
logTime ("Ajax complete");
//OPTION 2
return; //-- For compare test
if (config.url.indexOf ('/tab/') != -1){
$(".display.discog").each ( function () {
appendColumn ( $(this) );
} );
}
} );
$("#band_disco > ul > li").on ("click", "a.ui-tabs-anchor", function (zEvent) {
logTime (zEvent.target.textContent + " tab was clicked.");
} );
function logTime (lableTxt) {
var tNow = new Date ();
console.log (tNow.toLocaleFormat ('%H:%M:%S') + "." + tNow.getMilliseconds (), " <== " + lableTxt);
}
//OPTION 3
//*--- Remove leading slash, from this line, to comment out block, below.
var muteObserver = new MutationSummary ( {
callback: handleDiscographyChanges,
rootNode: $("#band_disco")[0],
queries: [ {element: ".discog"} ]
} );
//*/ -- Tail end of optional comment block
function handleDiscographyChanges (muteSummaries) {
var mSummary = muteSummaries[0];
if (mSummary.added.length) {
appendColumn ( $(mSummary.added[0]) );
}
}
请注意,此示例中省略了样式代码和一些原始 cmets。