2015-11-18 4 views
0

Я пишу много небольших пользовательских скриптов GreaseMonkey, как правило, для себя. Несмотря на то, что они выполняют свою работу, есть одна небольшая проблема, с которой я не могу разобраться:Пользовательские скрипты для динамических страниц?

Как мне работать с динамически меняющимися веб-сайтами?

Например, интернет-магазины, такие как Amazon, не перенаправляют все больше, когда нажимают на «Следующая страница» и вместо этого динамически обновляют фактические записи. У меня есть сценарий, чтобы выделить несколько вещей, но каждый раз, когда я переключаюсь на новую страницу, у меня есть F5 на всей странице.

Прямо сейчас я делаю это через onclick Событие, а затем 3-секундный тайм-аут перед повторным применением сценария, но я чувствую, что он довольно «грязный». Существуют ли более чистые методы?

+0

Какой браузер вы используете? Chrome или Firefox? –

+1

Новый загруженный контент должен быть выполнен с использованием ajax. Попробуйте посмотреть, не можете ли вы изменить эту функцию ajax, чтобы автоматически вызывать ваш сценарий на успех этого вызова ajax, а не на клик, он должен быть намного «чище». – user4467065

+1

@LongNguyen. Он использует GreaseMonkey, поэтому я предполагаю, что он использует Firefox. – Delgan

ответ

0

Ответ ниже опущен. Вместо этого вы должны использовать Use MutationObserver или setInterval. Смотрите это: Greasemonkey script to work on dynamically loaded posts on Facebook


Поскольку вы используете Firefox, вы можете провоцировать на DOMSubtreeModified событие.

Для этого сначала заверните часть кода вашего текущего скрипта в функцию; например:

// ==UserScript== 
// @name 
// ==/UserScript== 

function LocalMain() 
{ 
    //--- Do all of your actions here. 
} 

LocalMain(); //-- Fire GM script once, normally. 

Далее, если узел «DOM» изменился при нажатии «Следующая страница». Как только вы определили правильный узел, вы можете установить прослушиватель событий. Но вам также нужна короткая временная задержка, потому что изменения узлов происходят сотнями за раз, и вам нужно подождать, пока текущая партия не будет выполнена.

Таким образом, положить все это вместе, код выглядит следующим образом:

if (window.top != window.self) //don't run on frames or iframes 
    return; 

function LocalMain() 
{ 
    //--- Do all of your actions here. 
} 

LocalMain(); //-- Fire GM script once, normally. 


var ContentChangedByAJAX_Timer = ''; 
//--- Change this next line to find the correct element; sample shown. 
var ContentWrapperNode   = document.getElementById ('THE ID OF DOM NODE GOT UPDATE WHEN CLICKING ON NEXT PAGE'); 

ContentWrapperNode.addEventListener ("DOMSubtreeModified", PageBitHasLoaded, false); 


function PageBitHasLoaded (zEvent) 
{ 
    /*--- Set and reset a timer so that we run our code (LocalMain()) only 
     AFTER the last post -- in a batch -- is added. Adjust the time if needed, e.g. 3 seconds. 
    */ 
    if (typeof ContentChangedByAJAX_Timer == "number") 
    { 
     clearTimeout (ContentChangedByAJAX_Timer); 
     ContentChangedByAJAX_Timer = ''; 
    } 
    ContentChangedByAJAX_Timer  = setTimeout (function() {LocalMain(); }, 3000); 
} 
+2

Этот код от 5 лет назад? Это ужасно. Прекратите использование устаревших и медленных событий DOMSubtreeModified и подобных мутаций. Используйте MutationObserver или setInterval. – wOxxOm

+1

Автор этого кода уже предоставляет другую удобную функцию: [waitForKeyElements] (https://gist.github.com/2625891). – wOxxOm