2014-12-30 2 views
1

Нижеприведенный 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.

Я устанавливаю скрипт и перехожу к профилю Twitter. И у всех твитов есть строка 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

Несколько вещей, которые, как представляется, происходят:

  1. Когда изменения щебета в «новую» страницу, иногда сохраняют измененный текст, но громит данные Jquery, что waitForKeyElements использует для отслеживания узлов.

  2. При переходе на «новые», «нежелательные» страницы, поскольку загрузка на страницу отсутствует, сценарий не восстанавливается, а старый waitForKeyElements по-прежнему активен.

  3. Если вы начинаете на странице, вы не хотите корректировки, а затем переходите на страницу, если вы это делаете, тогда сценарий не срабатывает, потому что твиттер просто отображает новый URL-адрес, загрузите большую часть всего.

  4. Twitter загружает фреймы и сценарий стреляет в них тоже.


Чтобы обойти ЗЕ проблемы:

  1. отслеживать также измененные узлы жестким атрибутом - что твиттер не делает мусор.
  2. Измените @include на огонь по https://twitter.com/*, а затем используйте location.pathname, чтобы уточнить, что дальше.
  3. Деактивировать waitForKeyElements, когда AJAXing на нежелательные страницы.
  4. Монитор <title> изменяет как надежный способ обнаружения «новых» страниц.
  5. Использование @noframes.

Таким образом, этот сценарий должен работать лучше для вас (только проверенные на 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(); 
     } 
    }); 
} 
+0

Вау, который стал сложным, чем я сначала думал. Я протестировал скрипт в Firefox, и он работает хорошо! Спасибо. Не работает в Chrome, хотя по какой-то причине, но сейчас все в порядке. Можете ли вы объяснить, что происходит внутри предложения else функции 'fireMainCode()', пожалуйста? – Isuru

+0

Да, выяснилось, что Twitter в Chrome делает что-то, чтобы перекрыть некоторые из функций MutationObserver. Не хочу тратить много времени на это. ... Это предложение 'else' отключает экземпляр' waitForKeyElements' при переходе с «страницы», где вы хотите, чтобы функция была на странице, где вы этого не сделали (* Проблема 1 * в вашем вопросе выше). –

+0

Я вижу. Но почему существует шаблон регулярного выражения? В чем его цель? – Isuru