Twitter用户脚本会影响除预期(@included)之外的页面吗?

时间:2014-12-30 12:25:43

标签: jquery ajax twitter greasemonkey userscripts

以下UserScript适用于我自己的Twitter个人资料页面(不是时间轴)。

// ==UserScript==
// @name            CoolScript
// @include         https://twitter.com/IJNanayakkara
// @include         https://twitter.com/IJNanayakkara/status/*
// @require         http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require         https://gist.github.com/raw/2625891/waitForKeyElements.js
// @version         1.0
// @license         GPL v3 or any later version (http://www.gnu.org/copyleft/gpl.html)
// @grant           GM_addStyle
// ==/UserScript==

function prependToTweet(jNode) {
    jNode.prepend("Hello World ");
}

waitForKeyElements("p.js-tweet-text", prependToTweet);

它的作用是将给定的文本字符串附加到页面中每条推文的开头。

虽然脚本按我的意愿行事,但我面临两个问题。

1。脚本会影响@include中定义的页面以外的页面。

我安装脚本并转到我的推特个人资料。所有推文都将 Hello World 字符串添加到开头。这是预期的。

enter image description here

然后我转到我的时间轴页面,那里的所有推文都附加了 Hello World 字符串,这不是预期的行为。

enter image description here

我需要知道为什么会这样。


2。 Hello World 字符串字符串重复。

假设我点击推文在一个页面中查看。工作正常。

enter image description here

然后我回到我的个人资料页面。

enter image description here

如果我去其他页面并再次返回,则该字符串会再次重复。

enter image description here

这是我面临的两个问题。我认为这些是由于AJAX引起的,但我无法找到解决它的方法。

1 个答案:

答案 0 :(得分:1)

似乎正在进行一些事情:

  1. 当Twitter改变为" new"在页面中,它有时会保留修改后的文本,但会删除waitForKeyElements用于跟踪节点的jQuery数据。

  2. 导航到" new","不需要的"页面,因为没有页面加载,脚本不会重新启动,旧的waitForKeyElements仍处于活动状态。

  3. 如果您从一个页面开始,您不想进行调整,然后导航到某个页面,那么脚本不会触发,因为Twitter只显示了一个新的URL,它实际上并没有加载任何东西。

  4. Twitter正在加载iframe,并且脚本也会对这些内容进行解雇。


  5. 为解决这些问题我们:

    1. 还通过硬属性跟踪更改的节点 - 推特不会丢弃。
    2. @include更改为https://twitter.com/*,然后使用location.pathname进一步优化。
    3. 当AJAXing到不需要的页面时停用waitForKeyElements
    4. 监控<title>更改,作为检测&#34; new&#34;的可靠方法。页。
    5. 使用@noframes
    6. 所以,这个脚本应该更适合你(仅在Greasemonkey上测试,但在Tampermonkey上工作):

      // ==UserScript==
      // @name            Twitter: Modify tweets on select pages.
      // @include         https://twitter.com/*
      // @require         http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
      // @require         https://gist.github.com/raw/2625891/waitForKeyElements.js
      // @grant           GM_addStyle
      // @noframes
      // ==/UserScript==
      var tweetSelector = "p.js-tweet-text";
      
      function fireMainCode () {
          /*--- Only fire on desired pages. This fires on:
              twitter.com/IJNanayakkara*
              twitter.com/IJNanayakkara/status/*
          */
          if (/^\/IJNanayakkara(\/status\/)?/.test (location.pathname) ) {
              if ( ! this.WFKE_fired) {
                  waitForKeyElements (tweetSelector, prependToTweet);
                  this.WFKE_fired = true;
              }
          }
          else {
              //--- Undesired page, shut off waitForKeyElements
              if (this.WFKE_fired) {
                  this.WFKE_fired = null;
                  var controlObj      = waitForKeyElements.controlObj  ||  {};
                  var controlKey      = tweetSelector.replace (/[^\w]/g, "_");
                  var timeControl     = controlObj [controlKey];
                  if (timeControl) {
                      clearInterval (timeControl);
                      delete controlObj [controlKey]
                  }
              }
          }
      }
      fireMainCode ();
      
      function prependToTweet (jNode) {
          var altDoneFlag = jNode.attr ("data-altdoneflag");
          if ( ! altDoneFlag) {
              jNode.prepend ("XXXXX => ")
              .attr ("data-altdoneflag", "yes");
          }
      }
      
      /*--- Twitter uses some pretty screwy AJAX to "change" pages, but it at least
          changes the title. So listen for that to (re) trigger waitForKeyElements.
      */
      var myObserver  = new MutationObserver (titleChangeDetector);
      var obsConfig   = {
          //-- Subtree needed.
          childList: true, characterData: true, subtree: true
      };
      
      myObserver.observe (document, obsConfig);
      
      function titleChangeDetector (mutationRecords) {
          mutationRecords.forEach ( function (mutation) {
              //-- Sensible, Firefox
              if (    mutation.type                       == "childList"
                  &&  mutation.target.nodeName            == "TITLE"
              ) {
                  fireMainCode ();
              }
              //-- WTF, Chrome
              else if (mutation.type                      == "characterData"
                  &&  mutation.target.parentNode.nodeName == "TITLE"
              ) {
                  fireMainCode ();
              }
          } );
      }