Chrome扩展无法提取网页元素更新userCompletedQuestions数组问题
问题:Chrome扩展无法正确提取并更新已完成题目数组
我正在开发一款Google Chrome扩展,需要提取网页中类似<a href="/problems/non-overlapping-intervals/">435. Non-overlapping Intervals</a>的元素文本,存入userCompletedQuestions数组,用来和jobrequirementQn数组做匹配,但始终无法更新这个数组。想请教下,通过检查网页元素存储内容的方式有没有问题?
相关代码
document.addEventListener('DOMContentLoaded', function () { // Function to extract completed questions from the webpage const extractCompletedQuestions = () => { // Select all anchor elements that match the pattern const questionLinks = document.querySelectorAll('a[href*="/problems/"]'); // Array to store the extracted question topics let questionTopics = []; // Iterate over each link and extract the text questionLinks.forEach(link => { const questionText = link.textContent.trim(); questionTopics.push(questionText); }); // Store the question topics in chrome storage chrome.storage.local.set({ 'userCompletedQuestions': questionTopics }, function () { console.log('Completed questions saved:', questionTopics); }); }; // Function to initialize the pie chart const createChart = (data) => { const ctx = document.getElementById('pieChart').getContext('2d'); return new Chart(ctx, { type: 'pie', data: data, options: {} }); }; const updateChartData = (chart, data) => { chart.data.datasets[0].data = data; chart.update(); }; // Initialize data const data = { labels: ['Completed', 'Remaining'], datasets: [{ data: [0, 100], // Initial data backgroundColor: [ 'green', // Completed 'lightgray' // Remaining ] }] }; // Initialize chart let pieChart = createChart(data); // Add event listener to radio buttons const radioButtons = document.querySelectorAll('input[type="radio"]'); radioButtons.forEach(button => { button.addEventListener('change', function () { chrome.storage.local.get(['userCompletedQuestions', 'job1Questions', 'job2Questions'], function (result) { const userCompletedQuestions = result.userCompletedQuestions || []; let requiredQuestions = []; if (this.value === 'Job 1') { requiredQuestions = result.job1Questions || []; } else if (this.value === 'Job 2') { requiredQuestions = result.job2Questions || []; } const matchedQuestions = requiredQuestions.filter(question => userCompletedQuestions.includes(question)); const completedPercentage = Math.round((matchedQuestions.length / requiredQuestions.length) * 100); const remainingPercentage = 100 - completedPercentage; updateChartData(pieChart, [completedPercentage, remainingPercentage]); console.log('Pie chart updated:', pieChart.data.datasets[0].data); }); }); }); // Extract and store completed questions when the content script is loaded extractCompletedQuestions(); // Example of extracting a specific question title if needed let questionText = document.querySelector('.question-title')?.innerText; if (questionText) { chrome.runtime.sendMessage({ action: 'storeQuestion', question: questionText }, function (response) { console.log('Question data sent to background:', response); }); } });
问题分析与解决办法
你的提取逻辑本身没问题,但大概率是DOM加载时机或选择器精度的问题导致数组没正确更新:
1. 动态内容未被捕获
如果页面是单页应用(比如LeetCode),题目列表是通过AJAX/框架动态渲染的,DOMContentLoaded触发时,目标元素还没生成,querySelectorAll拿不到任何元素,自然存不了数据。
解决办法:用MutationObserver监听DOM变化,当题目容器更新时重新提取:
const observeQuestionsContainer = () => { // 替换成你页面中已完成题目所在容器的选择器,比如LeetCode的题目列表容器 const container = document.querySelector('.your-completed-questions-container'); if (!container) return; const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { if (mutation.addedNodes.length > 0) { extractCompletedQuestions(); } }); }); observer.observe(container, { childList: true, subtree: true }); }; // 初始化时启动监听 document.addEventListener('DOMContentLoaded', () => { extractCompletedQuestions(); observeQuestionsContainer(); });
2. 选择器范围太广
a[href*="/problems/"]会匹配所有包含该路径的链接,包括推荐题目、侧边栏无关链接,导致存入错误数据,甚至覆盖正确的已完成题目数组。
解决办法:查看已完成题目的DOM特征(比如有特定class、图标),精准定位:
// 示例:仅选择带有"ac"类(已完成标记)的题目链接 const questionLinks = document.querySelectorAll('a[href*="/problems/"].ac');
3. 验证提取与存储结果
在extractCompletedQuestions里加日志,确认是否拿到了正确的元素:
const extractCompletedQuestions = () => { const questionLinks = document.querySelectorAll('a[href*="/problems/"]'); console.log('找到的链接数量:', questionLinks.length); // 检查是否有元素被选中 let questionTopics = []; questionLinks.forEach(link => { const text = link.textContent.trim(); console.log('提取的题目文本:', text); // 检查文本是否正确 questionTopics.push(text); }); chrome.storage.local.set({ 'userCompletedQuestions': questionTopics }, () => { console.log('存储的数组:', questionTopics); }); };
另外,在读取存储时也可以加日志,确认数据是否正确读取:
chrome.storage.local.get('userCompletedQuestions', (result) => { console.log('读取到的已完成题目:', result.userCompletedQuestions); });
内容的提问来源于stack exchange,提问作者lum wenkang
相关产品推荐
相关产品推荐

