2014-01-14 2 views
5

С тех пор, как в прошлом году YouTube сделал это так, чтобы каждая страница не загружала совершенно новую страницу, но в основном просто загружала содержимое в div#content. Вы можете заметить это, когда вы нажимаете ссылку на YouTube и видите красную панель загрузки в верхней части страницы.Как запустить скрипт каждый раз, когда новая страница загружается на YouTube?

У меня есть сценарий Greasemonkey, который изменил элементы на YouTube, но теперь, когда YouTube не перезагружает всю страницу, сценарий Greasemonkey больше не срабатывает на каждой «новой» странице. Как я могу создать сценарий Greasemonkey на каждой «новой» странице, загружаемой на YouTube?

Я использую jQuery в этом сценарии Greasemonkey. Я пробовал использовать такие функции, как .on(), с DOMNodeInserted, но я не могу найти правильную комбинацию, чтобы она работала правильно. С слушателями событий, которые я использую, я в конечном итоге работаю мой сценарий сотню раз для каждой загрузки страницы, например, с помощью следующих действий:

$('div#page').on('DOMNodeInserted', 'div#content', function() { });

Другого решением я думал было сделать все ссылки на страницах загрузки YouTube, как обычно, без нового способа, которым они это делают.

+1

Прилагают eventlistener к содержимому div #. – Mike

+0

@Mike: Это достойный ответ, если вы предоставите образец короткого кода –

+0

Да, я ищу пример кода. Я знаю, что мне нужен прослушиватель событий, но я не могу найти нужную «комбинацию», чтобы он работал правильно на YouTube. Я делал это раньше на других сайтах, но YouTube немного отличается. – Gary

ответ

6

Я понял это после некоторых исследований. Во-первых, мне не нравятся решения, которые используют setTimeout. Это часто один из способов, предложенных в пользу устаревшего DOMNodeInserted (который я использую в некоторых моих сценариях, но стараюсь избегать как можно больше), но, если это возможно, я всегда предпочитаю решение, где сценарий фактически выполняется после конкретное событие. Я опубликовал решение, которое я изначально использовал в первом разделе ниже, а затем окончательное решение, которое я использовал во втором разделе. Для всего кода ниже требуется jQuery.

Достойное решение, но не самый лучший

Сначала я имел решение, в котором я добавил click событие для всех A элементов, которые будут запускать таймер, который бежал мой сценарий после 2-х секунд. Это не изящно, потому что, если страница загружается быстро, то есть секунда, где сценарий не запускается. И если страница загружается более двух секунд, сценарий не запускается вообще. Сценарий ниже:

$('a').click(function() 
{ 
    setTimeout(youtubeFunction, 2000); 
}); 

Гораздо лучшее решение

Так что я начал искать решение, которое было связано с тем, что я хотел сделать. В конце концов, я нашел других людей с подобной проблемой (например, людей, желающих создать скрипт Chrome, который изменяет страницы YouTube). Это привело меня к this particular Stack Overflow solution, в котором в основном говорится, что красная панель загрузки в верхней части страниц YouTube была элементом перехода CSS и что при ее завершении она создала событие (с учетом регистра). Код в связанном решении не был полным (для меня в любом случае), но он объяснил, как достичь рабочего решения. Код, который я запускаю только один раз на страницу, является идеальным.Так вот что я сейчас:

function youtubePageChange() 
{ 
    youtubeFunction(); 
    $('body').on('transitionend', function(event) 
    { 
     if (event.target.id != 'progress') return false; 
     youtubeFunction(); 
    }); 
} 

$(youtubePageChange); 

Чтобы объяснить код, приведенный выше, в основном я запускаю код один раз при первой загрузке страницы YouTube (например, введя URL-адрес в адресной строке). Затем для каждого последующего щелчка, который требует индикатор выполнения, код запускается снова.

Красный прогресс штрих-код

О, и в будущем, когда красный индикатор появляется в верхней части страницы YouTube, сайт временно добавляет новый DIV к концу BODY, с помощью следующего кода:

<div id="progress" class="waiting" style="transition-duration: 400ms; width: 99%;"><dt></dt><dd></dd></div> 
+0

Это работает для меня - спасибо! – jetcom

+1

У меня проблемы с этим сейчас. Это работает только в полтора раза. YouTube, должно быть, что-то изменил, и я не могу точно определить, что это такое. Я вернусь обратно к 'setInterval' пока, как резерв. – Gary

+0

То же самое здесь. Работает большую часть времени, но не все время – huyz

0

Hooking в popstate может быть вариант, но я не смог сделать эту работу правильно по какой-то причине (YouTube может быть предотвращая ее распространяющиеся), поэтому я придумал это, что показывает концепцию:

var currentState = ""; 
setInterval(function(){ 
    if (currentState != history.state["spf-referer"]) { 
     currentState = history.state["spf-referer"]; 
     console.log("Do Stuff!"); 
    } 
},250) 

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

+0

Могу ли я сделать что-то вроде использования события hashchange? Хотя я просто попробовал это, и он, похоже, не работает, но, возможно, что-то подобное может сделать трюк. – Gary

+0

Нет, потому что хэш не меняется. Правильное событие - событие popState, но, как я уже сказал, я не могу получить это для работы с youtube. Скорее всего, они остановятся. –

+0

Это тяжелая память, когда пользователь наблюдает за длинным видео. Видео в течение часа будет производить 14400 циклов проверки отходов. – mehulmpt

Смежные вопросы