Greasemonkey:监听表是否“刷新”

问题描述 投票:0回答:1

我正在开发一个 Tampermonkey/Greasemonkey 脚本,该脚本会在此页面上的表格中添加一个新列https://www.fangraphs.com/leaders/major-league.

我有一个工作版本,添加了该列,看起来像这样

fangraphs grid1

我希望能够在网格刷新时重新运行脚本(例如,当单击其中一个表标题对数据进行排序时)。问题是,如果我添加代码来观察表何时发生变化,它会在我添加列时触发。我确实注意到,当页面发生更改时,会向 DOM 添加一个 div,其中包含一个名为“fgui-loading”的类。有没有办法在初始页面加载后为该 div 添加观察者?

这是我的工作脚本,它添加了列,但正如您所看到的,对列进行排序不会更新最后一个列。


(function () {
  "use strict";

  // Mock function to get the free agent year of a player
  function getFreeAgentYear(playerName) {
    // In a real scenario, this data would be fetched from an API or database
    let freeAgentData =
      {
"Aaron Judge" : "FREE AGENT 2029",
"Juan Soto" : "After 2030"
};
    return freeAgentData[playerName] || "Not on Roster or After 2030";
  }

  // Function to add the "Free Agent Year" column
  function addFreeAgentYearColumn() {
    const table = document.querySelector(".table-scroll");
    if (!table) return;

    // Add the header for the new column
    const headerRow = table.querySelector("thead tr");
    if (headerRow) {
      const newHeader = document.createElement("th");
      newHeader.innerText = "Club Control";
      headerRow.appendChild(newHeader);
    }

    // Add the free agent year data for each player
    const rows = table.querySelectorAll("tbody tr");
    rows.forEach((row) => {
      const playerNameCell = row.querySelector("td a");
      if (playerNameCell) {
        const playerName = playerNameCell.innerText.trim();
        const freeAgentYear = getFreeAgentYear(playerName);

        const newCell = document.createElement("td");
        newCell.innerText = freeAgentYear;
        row.appendChild(newCell);
      }
    });
  }

  const initialObserver = new MutationObserver((mutations) => {
    var processed = false;
    mutations.forEach(() => {
      if (document.querySelector(".table-scroll")) {
        if (document.querySelector(".table-scroll")) {
          const table = document.querySelector(".table-scroll");
          if (
            table.querySelectorAll("tbody tr").length > 1 &&
            processed == false
          ) {
            addFreeAgentYearColumn();
            processed = true;
            initialObserver.disconnect();
          }
        }
      }
    });
  });

  initialObserver.observe(document.body, { childList: true, subtree: true });
})();

感谢对此的帮助!

javascript greasemonkey tampermonkey greasemonkey-4
1个回答
0
投票

观察

.fgui-loading
并不能解决问题,因为该元素仅在从网络获取数据时出现,一旦数据被缓存,它就不会再出现。

都不会监听标题上的点击,因为您仍然需要确保加载/刷新完成并插入新值,以便您的函数不会使用以前的值。

最简单/最简单的方法是观察

tbody
元素并在更新时调用
addFreeAgentYearColumn

这可以方便地处理更改页码或页面大小,甚至更改选项卡。

注意:我只在大联盟页面及其选项卡上测试了此代码,您可能需要调整它才能在其他页面上工作。

function getFreeAgentYear(playerName) {
    let freeAgentData =
        {
            "Aaron Judge" : "FREE AGENT 2029",
            "Juan Soto" : "After 2030"
        };
    return freeAgentData[playerName] || "Not on Roster or After 2030";
}


function addFreeAgentYearColumn() {
    const table = document.querySelector("div.table-scroll > table");
    if (!table) return;

    // disconnect observer to avoid infinite loop
    observer.disconnect();

    // remove old header/cells (from tables that don't have player names and avoid duplication)
    table.querySelectorAll('#club-control').forEach( ele => ele.remove() );

    // return if this table does not have a playerName header
    const playerNameHeader = table.tHead.querySelector("th[data-col-id=Name]");
    if (!playerNameHeader) return;

    const clubControlHeader = document.createElement("th");
    clubControlHeader.innerText = "Club Control";
    clubControlHeader.id = "club-control";
    table.tHead.rows[0].appendChild(clubControlHeader);

    const rows = table.tBodies[0].rows;
    for (let i=0; i < rows.length; ++i){
        //const playerNameCell = rows[i].cells[1];
        const playerNameCell = rows[i].querySelector("td[data-col-id=Name]");
        if (!playerNameCell) return;

        const playerName = playerNameCell.textContent;
        const freeAgentYear = getFreeAgentYear(playerName);

        const clubControlCell = document.createElement("td");
        clubControlCell.id = "club-control";
        clubControlCell.innerText = freeAgentYear;
        rows[i].appendChild(clubControlCell);
    };

    // reconnect the observer
    const target = table.tBodies[0];
    const config = {childList: true, subtree: true};
    observer.observe(target, config);
}

const observer = new MutationObserver(addFreeAgentYearColumn);
addFreeAgentYearColumn();
© www.soinside.com 2019 - 2024. All rights reserved.