Chrome扩展追踪推文内容返回undefined问题求助
兄弟,我懂你现在的糟心情况——想做个Chrome扩展追踪自己写的推文内容,结果每次拿到的都是undefined,这肯定让人头大。我帮你捋捋代码里的问题,还有对应的解决办法:
首先看你代码里的选择器转义错误,这大概率是核心问题:
你写的选择器里用了",这是HTML的实体转义字符,但在JavaScript字符串里完全不需要这么写!直接用双引号包裹属性值就行,不然浏览器根本识别不了这个选择器,自然document.querySelector就拿不到对应的输入框元素,最后tweetInput肯定是undefined。
把这段代码:
const tweetButtonSelector = 'div[data-testid="tweetButtonInline"]'; const tweetTextareaSelector = 'div[aria-label="Tweet text"]';
改成:
const tweetButtonSelector = 'div[data-testid="tweetButtonInline"]'; const tweetTextareaSelector = 'div[aria-label="Tweet text"]';
然后是推文内容的获取方式:
Twitter(现在叫X)的推文输入框是contenteditable类型的div,不是普通的textarea,有时候innerText在某些DOM状态下可能拿不到完整内容,换成textContent会更可靠,还可以加个空值判断:
if (tweetTextarea) { // 优先用textContent,兜底用innerText,同时去掉首尾空格 const tweetInput = tweetTextarea.textContent.trim() || tweetTextarea.innerText.trim(); if (!tweetInput) { console.log('推文内容为空哦'); return; } // 后续的存储逻辑 }
还有你的MutationObserver代码不完整,你只写了一半mutations.forEach((mutation) =&...,得把监听逻辑补全才行。其实更靠谱的是:要么监听输入框的内容变化(实时捕获输入),要么直接给推文按钮加点击事件监听,而不是靠延迟500ms去拿内容。
比如,给推文按钮加点击监听的完整逻辑:
function trackTweet() { const tweetTextarea = document.querySelector(tweetTextareaSelector); if (!tweetTextarea) { console.log('没找到推文输入框'); return; } const tweetInput = tweetTextarea.textContent.trim() || tweetTextarea.innerText.trim(); if (!tweetInput) { console.log('推文内容为空'); return; } console.log('用户要发的推文:', tweetInput); chrome.storage.local.set({ tweetInput: tweetInput }, function() { console.log('推文内容已保存:', tweetInput); }); } // 自动寻找推文按钮并添加监听,找不到就重试 function setupTweetButtonListener() { const tweetButton = document.querySelector(tweetButtonSelector); if (tweetButton) { tweetButton.addEventListener('click', trackTweet); } else { setTimeout(setupTweetButtonListener, 1000); } } // 页面加载后初始化监听 document.addEventListener('DOMContentLoaded', setupTweetButtonListener);
另外还要检查你的扩展权限配置,确保manifest.json里加了必要的权限和主机匹配:
{ "manifest_version": 3, "name": "推文追踪器", "version": "1.0", "permissions": ["storage", "activeTab"], "content_scripts": [ { "matches": ["https://twitter.com/*", "https://x.com/*"], "js": ["script.js"] } ] }
要是没加https://twitter.com/*和https://x.com/*的匹配规则,你的content script根本跑不起来,自然拿不到任何DOM元素。
最后,如果要在扩展的弹窗/设置页显示存储的推文内容,得用chrome.storage.local.get来读取:
// 比如在popup.js里 document.addEventListener('DOMContentLoaded', () => { chrome.storage.local.get('tweetInput', (result) => { const displayEl = document.getElementById('tweet-display'); if (result.tweetInput) { displayEl.textContent = result.tweetInput; } else { displayEl.textContent = '暂无已保存的推文内容'; } }); });
先把选择器的问题改了,这应该是导致你拿到undefined的最主要原因,然后再一步步优化其他逻辑,应该就能解决问题了!
备注:内容来源于stack exchange,提问作者Chenhao Zhang

