【问题标题】:Unable to send a variable from content script to popup无法将变量从内容脚本发送到弹出窗口
【发布时间】:2017-06-11 14:30:42
【问题描述】:

所以我一直在努力将“getVideo”从content.js(我的内容脚本)传递给popup.js。现在我从https://developer.chrome.com/extensions/messaging 复制只是为了尝试获取消息。但是,一旦页面打开,我就会在控制台上收到错误消息:Cannot read property 'farewell' of undefined。我已经尝试了与 Chrome 扩展消息相关的每个线程的每一个建议/答案,但没有任何效果。这让我相信我如何设置扩展程序有更多错误,但我不知道是什么。谢谢!

manifest.json

{
  "manifest_version": 2,

  "name": "JW Player Tools",
  "description": "This extension lets you speed up and download captions from a JW video",
  "version": "1.2.5",

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },

  "content_scripts": [
 {
   "matches": ["*://*.tower.la.utexas.edu/*"],
   "all_frames": true,
   "js": ["content.js"],
   "run_at": "document_idle"
 }]
}

popup.js

document.addEventListener('DOMContentLoaded', function() {


    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        console.log(sender.tab ?
                    "from a content script:" + sender.tab.url :
                    "from the extension");
      if (request.greeting == "hello")
        sendResponse({farewell: "goodbye"});
    });



    var playback = document.getElementById('playback');
    playback.addEventListener('click', function() {
        var newspeed = prompt("Current Speed: " + getVideo.playbackRate + "\nNew Speed: ");
        getVideo.playbackRate = newspeed;
    });

    var captions = document.getElementById('captions');
    captions.addEventListener('click', function() {
        for (index = 0; index < getVideo.textTracks[0].cues.length; ++index) {
            document.write(getVideo.textTracks[0].cues[index].text + " ");
        }
    });
});

内容.js

var waitForVideo = setInterval(checkForElement, 150);

function checkForElement() {
    var videoElem = document.getElementsByTagName('video');
    if (videoElem.length) {
        clearInterval(waitForVideo);
        var videolink = videoElem[0].getAttribute('src');
        getVideo = videoElem[0];



        chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
            console.log(response.farewell);
        });




    }
}

popup.html

   <!doctype html>
    <html>
      <head>
        <title>JW Tools</title>
        <script src="popup.js"></script>
      </head>
      <body>
        <button id="playback">Speed Up</button>
        <button id="captions">Download Captions</button>
      </body>
   </html>

【问题讨论】:

  • 请提供您的 popup.html 和您正在测试的网页的 HTML(或至少一个 URL)。
  • 使用名称 background.js 作为内容脚本的名称是个坏主意。作为后台脚本太容易混淆了。
  • 在您的内容脚本中,getVideo 是一个 DOM 元素。您将无法在消息中发送它。 DOM 元素不是 JSON 可序列化的。所有消息都必须是 JSON 可序列化的。您实际上并没有表现出试图将其作为消息发送,但您在第一句话中说这是您正在努力解决的问题。
  • 您不需要传递元素本身,只需传递文本数据:提取并发送。此外,您可能需要使用正确的 DOM 操作或 insertAdjacentHTML 而不是 document.write。
  • @umer936,我们可以建议,但正如 wOxxOm 所暗示的那样,该建议的一部分是您可能只需要包含在您想要发送消息的 DOM 元素中的部分信息,您可以提取和发送消息,或将处理移动到内容脚本中。我们不知道你需要什么元素,所以不能给出详细的建议。但是,假设您提供的代码与问题中描述的问题重复(我还没有尝试过),那么获取该信息实际上是一个不同的问题,应该是一个单独的问题。我会再次尝试代码并发表评论。

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

我解决了这个问题。我像这样将函数移到 content.js 中。

内容.js

var waitForVideo = setInterval(checkForElement, 150);

function checkForElement() {
    var videoElem = document.getElementsByTagName('video');
    if (videoElem.length) {
        clearInterval(waitForVideo);
        getVideo = videoElem[0];
    }
}

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
    if (request.task == "caption") {
        for (index = 0; index < getVideo.textTracks[0].cues.length; ++index) {
            document.write(getVideo.textTracks[0].cues[index].text + " ");
        }
    } else if (request.task == "speed") {
        var newspeed = prompt("Current Speed: " + getVideo.playbackRate + "\nNew Speed: ");
        getVideo.playbackRate = newspeed;
    } else {
        // sendResponse({});
    } 
});

并使用 popup.js 向 content.js 发送消息

document.addEventListener('DOMContentLoaded', function() {
    var playback = document.getElementById('playback');
    playback.addEventListener('click', function() {
        // var newspeed = prompt("Current Speed: " + getVideo.playbackRate + "\nNew Speed: ");
        // getVideo.playbackRate = newspeed;

        chrome.tabs.getSelected(null, function(tab) {
            chrome.tabs.sendRequest(tab.id, {
                task: "speed"
            }, function(response) {
                alert(response.farewell);
            });
        });

    });

    var captions = document.getElementById('captions');
    captions.addEventListener('click', function() {
        // for (index = 0; index < getVideo.textTracks[0].cues.length; ++index) {
        // document.write(getVideo.textTracks[0].cues[index].text + " ");
        // }

        chrome.tabs.getSelected(null, function(tab) {
            chrome.tabs.sendRequest(tab.id, {
                task: "caption"
            }, function(response) {
                alert(response.farewell);
            });
        });
    });
});

感谢您的帮助! @Makyen @wOxxOm

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    相关资源
    最近更新 更多