google chrome - How to access the webpage DOM rather than the extension page DOM? -


i'm writing chrome extension , trying overlay <div> on current webpage button clicked in popup.html file.

when access document.body.insertbefore method within popup.html overlays <div> on popup, rather current webpage.

do have use messaging between background.html , popup.html in order access web page's dom? in popup.html, , use jquery too, if possible.

as stated in chrome extensions overview: architecture (which must-read):

if extension needs interact web pages, needs content script. content script javascript executes in context of page that's been loaded browser. think of content script part of loaded page, not part of extension packaged (its parent extension).

a popup (browseraction icon in main google chrome toolbar right of address bar) html page chrome-extension:// url, if access dom, you're affecting page.
same applies background/options page.

to access/manipulate webpage dom have 2 ways:

  1. either declare content script(s) in manifest.json , use messaging:

    chrome.tabs.sendmessage() background/popup page injected content script's chrome.runtime.onmessage listener, perform actions on webpage , transfer results via sendresponse callback per documentation (note: json-ifiable objects numbers, strings, arrays, simple objects supported, means not dom elements, not classes, not functions). in case content script needs initiate communication extension page should use chrome.runtime.sendmessage().

  2. or use tabs api inject content script:
    chrome.tabs.executescript(tabid, details, callback)

    • required permissions: "tabs", "https://www.example.com/*"
      (or "<all_urls>", "\*://\*/\*", "http://\*/\*", "https://\*/\*")

    • a better choice, in case of explicit user activation, use "activetab" permission instead of "tabs" , "<all_urls>" because serves alternative many uses of "<all_urls>", displays no warning message during installation.

    • .executescript() may used callback function receives array of last evaluated expressions in injected content script, 1 element per each frame int it's injected within tab. chrome uses json.parse() , json.stringify() on results internally, restricting supported types plain objects , simple stringifiable values number/string, or arrays thereof.
      doesn't work dom elements, functions, custom properties, getters/setters: you'll need manually map/extract required data , pass in simple array/object.

content scripts execute in special environment called isolated world. have access dom of page injected into, not javascript variables or functions created page. looks each content script if there no other javascript executing on page running on. same true in reverse: javascript running on page cannot call functions or access variables defined content scripts.

it's still possible go level deeper , access webpage javascript variables/functions.



as example of second method, let's show div when browser action clicked.
we'll use chrome.tabs.executescript() in browseraction click handler inject content script file (or literal code string if it's small, see method's documentation) dom of page.

var somevar = {text: 'test', foo: 1, bar: false}; chrome.tabs.executescript({     code: '(' + function(params) {         document.body.insertadjacenthtml('beforeend',             '<div style="all:unset; position:fixed; left:0; top:0; right:0; bottom:0;' +                 'background-color:rgba(0,255,0,0.3)">' + params.text + '</div>'         );         return {success: true, html: document.body.innerhtml};     } + ')(' + json.stringify(somevar) + ');' }, function(results) {     console.log(results[0]); }); 

as can see, we've used automatic string conversion of function code able write injected code normal javascript syntax highlight , linting. obvious drawback browser wastes time parse code, it's less 1 millisecond negligible.


Comments

Popular posts from this blog

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -

python - Error while using APScheduler: 'NoneType' object has no attribute 'now' -