问题
I have a simple content script for my Chrome Extension that is supposed to grab the titles of YouTube videos. My problem is that it has only worked once. I tried accessing the child nodes of the HTMLCollection which should only be one but I get null of undefined. Doing something like:
element[0].innerText;
doesn't give me anything useful but from my understanding if I use getElementsByClassName and apply innerText on the first element with [0] it shoud work. It might be an issue with the html not being fully loaded as sometimes I get null but HTMLCollection always has the property that I want to access just sitting there.
Also:
element.length
returns 0.
This is what I usually get with my script.
Inside is the "innerText" property that I want to grab.
And this is what I got the one time it worked.
{
"manifest_version": 2,
"name": "test",
"author": "Muhammad Amer",
"description": "test",
"version": "1.0",
"content_scripts": [
{
"matches": [
"https://www.youtube.com/*"
],
"js": ["jquery-3.3.1.js", "content.js"]
}
],
"permissions": [
"https://www.youtube.com/*",
"tabs",
"activeTab",
"webNavigation"
]
}
var element = document.getElementsByClassName("title style-scope ytd-video-
primary-info-renderer");
console.log(element);
for (var i = 0; i < element.length; i++) {
var songTitle = element[i].innerText;
console.log(songTitle);
}
回答1:
With the help of the following post, I found a solution: 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'
The first issue was my code being executed too early so the setTimeout()
function solved that. The next issue was one I didn't know I would have until it was mentioned; YouTube loads it's pages dynamically so the content script only runs if the page refreshes which effectively may never happen. So mutationObserver()
worked to solve that problem as suggested in the comments. One peculiar thing was that I had to observe the childlist and subtree for mutations instead of characterData even though the character data was what the thing that changed. From what I've read the old node is removed and the new one then inserted.
Here is the code:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length) {
if (mutation.type == 'childList') {
console.log(mutation.target.innerText);
}
}
})
})
function checkNode() {
var targetNode = document.querySelector("h1.title.style-scope.ytd-video-primary-info-renderer");
if (!targetNode) {
window.setTimeout(checkNode, 500);
return;
}
console.log(targetNode.innerText);
var config = {
childList: true,
subtree:true
}
observer.observe(targetNode, config)
}
checkNode();
来源:https://stackoverflow.com/questions/54322626/chrome-extension-content-script-grabbing-youtube-video-titles-using-javascript