即使用户导航到另一个页面,如何在选项卡中注入内容脚本?

时间:2016-10-27 04:01:15

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

我正在开发Chrome扩展程序,其中包含 popup.js background.js myscript.js (内容脚本)。每当我点击扩展图标时,通过browserAction启动一个类型为panel的新窗口。然后,当我点击'记录'在我的面板窗口中, popup.js 将消息传递给 background.js

popup.js

$("#rcrd_btnr").click(function(ee)
{
    alert('about to start recoding');

    //send message from popup.js to background.js
    chrome.runtime.sendMessage({from : 'record'});

    'rcrd_btn_blue' is a button to stop the recording of events on page //
    $("#rcrd_btn_red").hide();
    $("#rcrd_btn_blue").show();
});

此外, background.js 将消息传递给 myscript.js (内容脚本),

background.js

if(request.from === 'record')
{
    chrome.browserAction.setBadgeBackgroundColor({ tabId : actvTabId,color: "green" });
    chrome.browserAction.setBadgeText({tabId : actvTabId,text: 'R'});
    chrome.tabs.query({active:true}, function(tabs)
    {
        for(var i=0;i<tabs.length;i++)
        {
            if(tabs[i].selected == true)
            {
                try
                {
                    //send to active tab to myscript from backgrund_record
                    chrome.tabs.sendMessage(tabs[i].id, {
                        from : 'btn_record',
                        win_id:windo.id
                    }, function(response) {});
                }
                catch(e)
                {
                    alert('sending failed');
                }
            }
        }
    });
}

然后,在 myscript.js 中,我有两个事件:

$( "body" ).click(function( event ){...});

$("input").change(function(eventChange){...});

这些活动捕获任何“点击次数”。和&#39;用户类型&#39;在活动选项卡上,将它们发送回 background.js ,然后再发送到 popup.js

myscript.js (内容脚本):

if(message.from === 'btn_record')
{
    $( "body" ).click(function( event ) 
    {
        try
        {
            //find element being clicked 
            var ele = document.getElementsByTagName(event.target.nodeName);

            //sending message back to background.js
            chrome.runtime.sendMessage({from : 'btn_record_myscript',msg : 'clicked'});
        }
        catch(e)
        {
            alert(e);
        }
    });

    //change event for 'input type=text'
    $("input").change(function(eventChange)
    {
        var ele = document.getElementsByTagName(eventChange.target.nodeName);
        //sending message back to background.js 
        chrome.runtime.sendMessage({from : 'btn_record_myscript',  msg :'typed'});
    });
}

问题:
每当我点击&#39;记录&#39;按钮,它成功捕获活动选项卡上的两个事件(我最后一个焦点的选项卡)。但是,当我单击页面上的任何超链接时,页面将导航到同一选项卡上的另一个页面。然后,我无法检测到新页面上的任何事件,即使它们位于同一个选项卡中。

如何重新注入内容脚本或保持注入?我在这个阶段很困难。

如果需要,我准备提供任何进一步的信息。

###### ###### UPDATE

$$$$$使用JQUERY文件也是

All Files Gist

popup.js

var rcrd_btn_cntr=0;
      $(document).ready(function()    {

            //listen mssage from record_button_red
            $("#rcrd_btnr").click(function(ee)
            {
                //alert('about to start recoding');

                //send message from record_to_background
                chrome.runtime.sendMessage({from : 'record'});
                // console.log(ws);
                $("#rcrd_btnr").hide();
                $("#rcrd_btnb").show();
            });

            //listen mssage from record_button_blue
            $("#rcrd_btnb").click(function(ee)
            {
                alert('about to stop recoding');
                $("#rcrd_btnb").hide();
                $("#rcrd_btnr").show();
                //send messagee from record_Button_stop
                chrome.runtime.sendMessage({from : 'cancel'});
            });


    //Listens for message coming from background
            chrome.runtime.onMessage.addListener(function (answer)
            {
            if(answer.from === 'b_r_m_background')
                {
                    if(typeof(answer) != 'undefined')
                    {
                        var row = '<tr><td>'+answer.command+'<td>'+answer.target+'<td>'+answer.value;
                        $('#mytbl').append(row);
                        console.log(answer.msg)
                        //alert(answer.msg);
                    }
                 }
            });


   });  

background.js

//create new window of type panel
var run =0;
var win_id;
var ifClosed=1;
var vid=0;
var xx ;
var actvTabId;


    chrome.browserAction.onClicked.addListener(function(tab) 
    {
    chrome.tabs.getSelected(null, function(tab) { 
    actvTabId = tab.id
    });



        chrome.windows.getCurrent(function(win)
        {
            xx = win;
            if(run==0 && ifClosed ==1)
            {
                chrome.windows.create({ type:"panel",url: "index.html","width" : 400,"height" : 600}, function(win) 
                {
                    win_id = win.id;
                //  alert('creating '+win_id);
                    run++;
                    ifClosed=0;
                });
            }
            else if(ifClosed == 0)
            {
                //alert('updating '+win_id);
                chrome.windows.update(win_id, {focused: true});
            }

        });
    }); 


        //listen for a message coming from panel_window
        chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) 
        {

            if(request.from == 'cancel')
            {

                //sending to active tab (myscript) from back 

                    //console.log('sending to myscript from back_cancel');
                    //console.log(sender);
                    chrome.tabs.query({active:true}, function(tabs)
                    {
                        for(var i=0;i<tabs.length;i++)
                        {
                            if(tabs[i].selected == true)
                            {
                                //chrome.tabs.update(tabs[i].id, {selected: true});
                                //send to active tab to myscript from back_cancel_button
                                chrome.tabs.sendMessage(tabs[i].id, {from : 'btn2_2_cancel'}, function(response) {});
                            }
                        }
                    });
                //console.log('sent from back.js');



            }
            //listen incoming from panel_window_record_button
            else if(request.from === 'record')
            {

                chrome.tabs.query({active:true}, function(tabs)
                {
                    for(var i=0;i<tabs.length;i++)
                    {
                        if(tabs[i].selected == true)
                        {
                            //chrome.tabs.update(tabs[i].id, {selected: true});
                            //sending to active tab (myscript) from back 
                            try
                            {
                            //send to active tab to myscript from backgrund_record
                            chrome.tabs.sendMessage(tabs[i].id, {from : 'btn_record',win_id:xx.id}, function(response) {});
                            }
                            catch(e)
                            {
                                alert('record background send failed');
                            }
                        }
                    }
                });
            }
            //listen incoming from active tab from myscript for logging events
            else if ( request.from =='btn_record_myscript' )
            {
                //send to panel window from background for logging events
                chrome.runtime.sendMessage({from:'b_r_m_background',msg : request.msg});
            }

        });


//when panel_window is closed
        chrome.windows.onRemoved.addListener(function (event)
        {

        chrome.browserAction.setBadgeText({tabId : actvTabId,text: ''});
            ifClosed = 1;
            run=0;  
            //alert(ifClosed);
            //alert('window is closed');
            chrome.tabs.query({active:true}, function(tabs)
            {
                for(var i=0;i<tabs.length;i++)
                {
                    if(tabs[i].selected == true)
                    {
                    chrome.tabs.sendMessage(tabs[i].id, {from : 'btn2_2_cancel'}, function(response) {});
                    }
                break;
                }
            });
        });

myScript.js

var cntr=0;
var cbtr2=0;
var typed = '';
var tp='null';
var isFirstTime=0;

        $(document).ready(function()    
        {
            //listen for incoming from background
            chrome.extension.onMessage.addListener(function (message,sender, sendResponse)
            {

                //listen incoming from cancel_button_background_panel_window
                if(message.from === 'btn2_2_cancel')
                {
                    //console.log('cencelling');
                    //in case of 'panel window close' or 'cancel button click' unbind all events from page
                    $('body').unbind('mouseover');
                    $('body').unbind('mouseout');
                    $('body').unbind('click');
                    $('body').unbind('keydown');

                }

                else if(message.from === 'btn_record')
                {

                    current_loc = window.location.href;
                    $( "body" ).click(function( event ) 
                    {                   

                            //find element being clicked 
                            var ele = document.getElementsByTagName(event.target.nodeName);
                        //  alert('sending from click');

                            chrome.runtime.sendMessage({from : 'btn_record_myscript',msg : ele[0]});

                    });

                    //change event for 'input type=text'
                    var key_detect;
                    $("input").change(function(eventChange)
                    {
                    var ele = document.getElementsByTagName(eventChange.target.nodeName);

                        //key detect event  
                        $("body").keydown(function (eventKey)
                        {
                            key_detect = eventKey.key;
                        });
                        //check if user has pressed enter 
                        if(key_detect == 13 || eventChange.type == 'change')
                        {               
                            typed = eventChange.target.value;
                        //  alert('sending from type');
                            chrome.runtime.sendMessage({from : 'btn_record_myscript', msg : ele});
                        }
                    });

                }
                else
                {
                alert('error');
                }


            });
////////onMessage Listener ends///////////      
                });

的index.html

<!doctype html>
<html lang="en">
<head>
<script src="jquery.js"></script>
  <script src = "popup.js"></script>

  <meta charset="utf-8">


  <title>My AddOn</title>

  <link rel="stylesheet" type="text/css" href="mycss.css"/>
</head>
<body >

<div>
<input type="button" value="Re" id ="rcrd_btnr" name="record"  style="position:absolute;left:40%;text-align: center;background-color : red ;text-decoration: bold;font-size: 10px;padding:10px 10px;border: none;color: white;cursor: pointer;border-radius:100%"/> 
<input type="button" value="Re" id ="rcrd_btnb" name="record"  hidden style="position:relative;left:40%;text-align: center;background-color : blue ;text-decoration: bold;font-size: 10px;padding:10px 10px;border: none;color: white;cursor: pointer;border-radius:100%"/> 
</div>
</body>
</html>

的manifest.json

{
    "name": "TestExtension",
    "version": "1.0.0",
    "manifest_version": 2,
    "description" : "Test Descr.",
    "icons": { "48": "bear.png"},

    "browser_action": {
        "default_icon": { "16": "bear.png", "32": "bear.png" },
        "default_title": "Test Addon"
    },
    "permissions": ["tabs"],
    "background": {
        "scripts": ["background.js"]
    },
    "content_scripts": [{
        "matches": ["http://*/*", "https://*/*"],
        "js": ["jquery.js","popup.js","myScript.js"]
    }]
}

1 个答案:

答案 0 :(得分:1)

我已经解决了这个问题。我所做的是,我有一个监听器来检查点击对象是否是 myscript.js 中的超链接和 chrome.onUpdated API background.js 。每当用户点击超链接时,消息就会发送到 background.js 中的 chrome.onUpdated API。其中我使用 setTimeout 再次注入 myscript.js