使用waitForKeyElements,是否可以阻止显示关键元素,并且只有在我的代码修改后才能显示它?

dar*_*red 1 javascript css ajax jquery greasemonkey

我有这个用户脚本 (在Stack Overflow的帮助下写的)用于网站metal-archives.com.

它的结构是这样的:

function appendColumn(...) {
    // code for appending column
    // code for making the table sortable   
}

waitForKeyElements ("table", appendColumn);        
Run Code Online (Sandbox Code Playgroud)

当您切换子标签(表格)时,脚本可以正常工作,除了视觉故障/延迟.

切换时,额外(第6列)最初显示为预期.但是,表格会以原始形式暂时显示,然后最终显示第6列.

要查看此内容,请安装脚本,访问此典型目标页面,然后切换子选项卡(完成唱片,主要,生命,演示,杂项等).
它看起来像这样:

桌子


我试图通过添加以下内容来显示初始表:

GM_addStyle(".display.discog {display: none;} ");
Run Code Online (Sandbox Code Playgroud)

到和的开头appendColumn():

GM_addStyle(".display.discog {display: inline !important;} "); 
Run Code Online (Sandbox Code Playgroud)

到了最后appendColumn().
但它没有任何区别.


我在该页面上使用了Firefox网络监视器,当你切换标签时似乎:

  • 代码会立即修改表(从缓存中加载?? - 因为网络监视器中没有条目).
  • 然后从服务器加载表(相关的HTML文件).
  • 然后最后一次修改表.

如何更改代码(使用waitForKeyElements时)以防止显示关键元素,并仅在我的代码修改后显示它?

或者我如何加快响应速度?

谢谢.

Bro*_*ams 5

我加载了你的脚本,添加了时序线并对其进行了测试.从AJAX完成到表修复完成所用的时间仅为400到500毫秒!对于大多数人和情况来说,这是非常快的.

但是,对于那些你绝对想要挤出毫秒的时候,你可以切换到MutationObservers.这些都是挑剔,脆弱,并且不那么跨浏览器便携,但它们很快.
在这种情况下,MutationObservers将AJAX到固定表的时间缩短到20到40毫秒的范围.

我建议使用像Mutation Summary这样的库来消除这个过程带来的一些痛苦.

要从简单的 waitForKeyElements()实现转换为Mutation Summary:

  1. @require https://raw.githubusercontent.com/rafaelw/mutation-summary/master/src/mutation-summary.js
    
    Run Code Online (Sandbox Code Playgroud)

    到您的元数据块.

  2. 将waitForKeyElements回调和简单选择器插入此结构:

    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]) );
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

例如,在这种情况下,更改:

waitForKeyElements (".display.discog", appendColumn);
Run Code Online (Sandbox Code Playgroud)

至:

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]) );
    }
}
Run Code Online (Sandbox Code Playgroud)

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]) );
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,此示例中省略了样式代码和一些原始注释.