首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从浏览器操作弹出:打开一个新的选项卡并填充输入字段

从浏览器操作弹出:打开一个新的选项卡并填充输入字段
EN

Stack Overflow用户
提问于 2016-12-12 01:54:38
回答 1查看 3K关注 0票数 4

我正在尝试构建一个基本的Chrome扩展,从一个浏览器操作弹出,在一个新的选项卡中打开一个网站,并填写登录凭据。我可以让Chrome扩展打开新页面,但似乎无法将其输入到输入字段中。

Manifest.json

代码语言:javascript
复制
{
  "manifest_version": 2,

  "name": "Vena",
  "description": "This extension will allow users to login to vena accounts",
  "version": "1.0",

  "browser_action": {
   "default_icon": "images/icon.png",
   "default_popup": "popup.html"
  },
  "permissions": [
   "activeTab"
   ]
}

popup.html

代码语言:javascript
复制
<!doctype html>
<html>
  <head>
    <title>Auto-Login</title>
    <script src="popup.js"></script>
  </head>
  <body>
    <h1>Login</h1>
    <button id="checkPage">Login!</button>
  </body>
</html>

popup.js

代码语言:javascript
复制
document.addEventListener('DOMContentLoaded', function() {
  var checkPageButton = document.getElementById('checkPage');
  checkPageButton.addEventListener('click', function() {

    var newURL = "https://vena.io/";
    chrome.tabs.create({ url: newURL });

    var loginField = document.getElementsByClassName('js-email form-control input-lg');
    var passwordField = document.getElementsByClassName('js-password form-control input-lg');

    loginField.value = 'gsand';
    passwordField.value = '123';


  }, false);
}, false);

如何填写新选项卡输入区域中的信息?

EN

回答 1

Stack Overflow用户

发布于 2016-12-12 05:15:16

另一次,您可能需要使用弹出窗口以外的其他内容(例如,简单的浏览器操作按钮或面板)来测试您的功能。由于弹出窗口在如此多的条件下会消失,所以调试其他东西比弹出窗口更容易。一旦调试了基本功能,就可以将其移动到弹出窗口中,并处理与使用弹出窗口相关的问题。

问题

您需要使用 内容脚本 与网页进行交互:

主要问题是,您必须使用内容脚本来与网页进行交互,例如您想要做的操作DOM。内容脚本必须注入到网页中。这可以通过在您的manifest.json中使用manifest.json条目,或者使用背景上下文中的来自JavaScript的chrome.tabs.executeScript() (背景脚本、事件脚本、弹出窗口、面板、包含来自外接程序页面的选项卡等)来完成。对于你正在做的事情,chrome.tabs.executeScript()是最好的选择。

附加问题:

  1. chrome.tabs.create()是异步的。您需要等待回调的执行,这样选项卡才会存在,以便注入内容脚本。不能将脚本插入到尚未存在的选项卡中。注意:您可以使用其他更复杂的方法来确定何时注入内容脚本,但是在本例中,chrome.tabs.create()的回调是一种很好的方法。
  2. 一旦创建了新的选项卡,就需要注入脚本。这不是“活动选项卡”,因此需要将"https://vena.io/*"添加到https://developer.chrome.com/extensions/manifest中的permissions中。
  3. 在运行内容脚本时,您希望与之交互的元素不会立即在页面上可用。你需要等到他们有时间。我只是使用一个setTimeout循环来轮询,直到元素可用为止。我选择每隔250 25进行一次轮询,最多100次(25秒)。在第一次延迟之后,这些元素每次都出现在那里。
  4. document.getElementsByClassName()返回一个HTMLCollection,而不是一个元素。
  5. 弹出窗口在激活其他选项卡时关闭。一旦弹出窗口关闭/销毁,您就不能在弹出窗口的代码中进行任何处理。为了解决这个问题:
    1. 在您的chrome.tabs.create()中,包含active:false以防止新选项卡立即激活。
    2. chrome.tabs.executeScript()回调中调用chrome.tabs.executeScript(),在注入内容脚本后激活选项卡(即当您在弹出窗口中完成所有处理时)。

代码

只需要在manifest.json和popup.js中进行更改。

manifest.json

代码语言:javascript
复制
{
  "manifest_version": 2,

  "name": "Vena",
  "description": "This extension will allow users to login to vena accounts",
  "version": "1.0",

  "browser_action": {
     "default_icon": "icon.png",
     "default_popup": "popup.html"
  },
  "permissions": [
    "activeTab", //This is not needed as you never interact with the active tab
    "https://vena.io/*"
  ]
}

popup.js

代码语言:javascript
复制
document.addEventListener('DOMContentLoaded', function() {
  var checkPageButton = document.getElementById('checkPage');
  checkPageButton.addEventListener('click', function() {
    var newURL = "https://vena.io/";
    //Must not make the tab active, or the popup will be destroyed preventing any
    //  further processing.
    chrome.tabs.create({ url: newURL,active:false }, function(tab){
        console.log('Attempting to inject script into tab:',tab);
        chrome.tabs.executeScript(tab.id,{code:`
            (function(){
                var count = 100; //Only try 100 times
                function changeLoginWhenExists(){
                    var loginField = document.getElementsByClassName('js-email form-control input-lg')[0];
                    var passwordField = document.getElementsByClassName('js-password form-control input-lg')[0];
                    //loginField and passwordField are each an HTMLCollection
                    if( loginField && passwordField ){
                        loginField.value = 'gsand';
                        passwordField.value = '123';
                    } else {
                        if(count-- > 0 ){
                            //The elements we need don't exist yet, wait a bit to try again.
                            //This could more appropriately be a MutationObserver
                            setTimeout(changeLoginWhenExists,250);
                        }
                    }
                }
                changeLoginWhenExists();
            })();
        `},function(results){
            //Now that we are done with processing, make the tab active. This will
            //  close/destroy the popup.
            chrome.tabs.update(tab.id,{active:true});
        });
    });
  }, false);
}, false);

可能需要使用document.execCommand('insertText', false, text);

根据页面的不同,您可能需要/希望使用:

代码语言:javascript
复制
document.execCommand('insertText', false, textValue);

如果这样做,您将需要首先选择/聚焦所需的元素。这将代替设置.value属性。您所使用的内容将取决于您实际在做什么,以及您正在更改的页面的组成。对于问题中的特定示例,设置元素的.value属性有效。对于插入文本,使用`document.execCommand('insertText')更适用。

可能需要一个MutationObserver

在上面的代码中,我使用一个setTimeout()循环来延迟,直到需要的元素存在。虽然这在上面的案例中有效,但取决于您的用例,您可能更适合使用MutationObserver。在很大程度上,使用哪种将取决于您需要如何立即响应所需添加的元素,以及通过查找元素在页面上放置何种类型的负载。有关监视DOM更改的更多信息,请参见:有JavaScript/jQuery更改监听器吗?

UI注释

目前,您有一个弹出,其中有一个单一的按钮:“登录”。从用户交互的角度来看,使用普通浏览器操作按钮可能会更好。如果您打算向弹出窗口添加功能,请继续并保留弹出窗口。如果您不打算添加功能,那么强迫您的用户单击两次(单击:打开弹出,然后单击:登录)是没有什么意义的,因为他们只点击了一次。

使用实际密码管理器

如果这是您想要的功能,而不是仅仅为了学习而将其组合在一起,那么您应该使用一个实际的密码管理器。安全地存储密码并在网站中适当地插入密码的功能并不简单。你很容易犯错误,结果会损害你的安全。我强烈建议你调查各种可用的,并选择一个适合你的需要。基本上,我看到的所有这些功能都可以很容易地为您提供您此时拥有的功能:打开弹出窗口;选择站点;转到站点并填写用户名和密码。密码管理器是一个非常重要的项目。这是,而不是,它是一个可以轻松处理的项目,或者是那些在安全问题上没有经验的人。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41093206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档