Расширения Firefox: как запускать функцию при каждой смене видео на YouTube - PullRequest
2 голосов
/ 30 марта 2019

У меня есть расширение, которое вводит код js на страницы YouTube.Я использовал следующее объявление в manifest.json:

"content_scripts": [
    {
        "matches": [
            "*://*.youtube.com/*"
        ],
        "js": [
            "background.js"
        ]
    }
]

Я хотел бы определить функцию, которая печатает название видео, количество лайков и дислайков на консоли, когда я перехожу к другому видео.

Я написал это в background.js:

window.onhashchange = function () {
    console.log(
        document.querySelector("h1.title > yt-formatted-string:nth-child(1)").innerHTML, "\n",
        document.querySelector("ytd-toggle-button-renderer.ytd-menu-renderer:nth-child(1) > a:nth-child(1) > yt-formatted-string:nth-child(2)").getAttribute("aria-label"), "\n",
        document.querySelector("ytd-toggle-button-renderer.style-scope:nth-child(2) > a:nth-child(1) > yt-formatted-string:nth-child(2)").getAttribute("aria-label"), "\n",
    )
}

Но он запускается только один раз.Если я выберу новое видео из раздела «Рекомендуется», оно не будет работать.Я также пытался .onload, .onunload и т. Д.

UPD: теперь я нашел единственный способ - использовать .setInterval.

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Несколько возможных решений, использующих WebExtensions API , все требуют фонового скрипта, который будет отправлять сообщения в ваш контент-скрипт.Измените ваш manifest.json так, чтобы он включал:

"background": {
    "scripts": ["background.js"]
}

Я назвал фоновый скрипт background.js, который будет конфликтовать с тем, что у вас есть в данный момент - вы можете подумать опереименуйте ваш скрипт содержимого в что-то вроде contentscript.js, чтобы вы не запутались.

В contentscript.js у вас есть прослушиватель сообщений

browser.runtime.onMessage.addListener(message => {
    if (message.videoChanged) {
        // do stuff
    }
});

Использование tabs.onUpdated

Необходимое разрешение в manifest.json

"permissions": [
    "tabs"
]

В background.js

browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    if (!changeInfo.url) {
        // url didn't change
        return;
    }

    const url = new URL(changeInfo.url);
    if (!url.href.startsWith('https://www.youtube.com/watch?') ||
        !url.searchParams.get('v')) {
        // not a youtube video
        return;
    }

    browser.tabs.sendMessage(tabId, {videoChanged: true});
});

Этот метод будет сообщать сценарий содержимого при первых посещениях во время навигации по сайту или автоматического воспроизведения.


Использование webNavigation.onHistoryStateUpdated

Необходимое разрешение вmanifest.json

"permissions": [
    "webNavigation"
]

В background.js

browser.webNavigation.onHistoryStateUpdated.addListener(history => {
    const url = new URL(history.url);
    if (!url.searchParams.get('v')) {
        // not a video
        return;
    }

    browser.tabs.sendMessage(history.tabId, {videoChanged: true});
},
    {url: [{urlMatches: '^https://www.youtube.com/watch\?'}]}
);

Этот метод отправляет сценарий содержимого во время навигации по сайту или автоматического воспроизведения.


Используя webRequest.onBeforeRequest или webRequest.onCompleted

YouTube делает xmlhttrequest при изменении видео.Вы можете просмотреть запросы, открыв Инструменты разработчика (Ctrl + Shift + I), выбрав вкладку «Сеть», выберите XHR, выполните фильтрацию по watch?, а затем разрешите YT переключиться на следующее видео.Вы увидите, что для следующего видео возникают два запроса: один с параметром prefetch в URL-адресе незадолго до его изменения, а другой - когда видео действительно изменяется без параметра prefetch.

Необходимразрешения в manifest.json

"permissions": [
    "https://www.youtube.com/watch?*",
    "webRequest"
]

В background.js

browser.webRequest.onBeforeRequest.addListener(request => {
    const url = new URL(request.url);
    if (!url.searchParams.get('v') || url.searchParams.get('prefetch')) {
        // not a video or it's prefetch
        return;
    }

    browser.tabs.sendMessage(request.tabId, {videoChanged: true});
},
    {urls: ['https://www.youtube.com/watch?*'], types: ['xmlhttprequest']}
);

onBeforeRequest могут быть слишком быстрыми и отправлять сообщение в сценарий содержимого перед новым видеофактически закончил загрузку.В этом случае вы можете просто заменить его на onCompleted.

. Этот метод выводит скрипт содержимого во время навигации по сайту или автоматического воспроизведения.

0 голосов
/ 30 марта 2019

Идея состоит в том, чтобы найти способ периодически проверять изменение URL-адреса, поэтому хитрость, которую я использую, заключается в том, чтобы воспользоваться потребностью пользователя нажимать на такие вещи, как кнопка воспроизведения / паузы и, конечно, на другие видео для просмотра.

Итак, внутри вашей страницы onload событие ... (W ваш идентификатор iframe)

 if(W.contentWindow.document.URL.indexOf('www.youtube.com/watch?v=')>-1){ // You may want to add some more permissable URL types here

   W.contentWindow.document.body.addEventListener('click',function(e){ CheckForURLChange(W.contentWindow.document.title,W.contentWindow.document.location); },false);

 }

А дальше с остальными вашими функциями ...

function CheckForURLChange(Title,URL){

  // Your logic to test for URL change and take any required steps

 if(StoredURL!==URL){}

 }

Это не лучшее решение, но оно работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...