Freewind
Freewind

Reputation: 198248

Insert a button to current page by chrome extension, but some methods are not working

I'm writing a very simple chrome extension which adds a button to current page.

manifest.json

{
  "manifest_version": 2,
  "name": "chrome-extension-tabs-executescript-add-button-demo",
  "description": "Chrome Extension Add Button Demo",
  "version": "1.0",
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "activeTab"
  ]
}

popup.html

<!doctype html>
<html>
<head>
    <title>Chrome Extension Add Button Demo</title>
    <script src="popup.js"></script>
</head>
</html>

popup.js

chrome.tabs.executeScript({
    file: "add-button.js"
}, function() {
    console.log("add-button.js injected")
})

add-button.js

var button = document.createElement("button")

button.innerText = "This is the inserted button, click on me!"
button['id'] = 'inserted'
button['data-name'] = 'name1'
button.onclick = function() {
    alert('clicked!')
}
button.fun = function() {
    alert('fun!')
}

document.body.appendChild(button)

Problems

It's almost working well, that if we clicked the extension icon for current page, and type following code in browser's console:

let button = document.getElementById('inserted');
button.click();

there is an alert means it's working.

But when calling fun() on it:

button.fun();

it reports such error:

Uncaught TypeError: button.fun is not a function

Can't understand why fun is missing.

Also provide a simple but complete demo if you need it: https://github.com/chrome-demos/chrome-extension-tabs-executescript-add-button-demo


I see in other answers it says content scripts run in a "isolated world", that the page and the content script and only see the same DOM, but not the variables defined in each other. My question puzzled me is, both onclick and fun are all functions defined on the DOM, why only one of them can work well.

I guess, the code run in content script

button.onclick = function() {
    alert('clicked!')
}
button.fun = function() {
    alert('fun!')
}

defines two functions, but they are not considered the same.

The onclick is a standard attribute of the shared DOM, so it adds to the DOM directly, which can be seen in page context.

But the fun method is not, so won't be added to the shared DOM, instead, it adds to somewhere else (maybe a child instance of the shared DOM), just stay in the scope of chrome content script.

Is my guess correct?

Upvotes: 3

Views: 3872

Answers (1)

Denis L
Denis L

Reputation: 3292

You right. Web pages and content-scripts share the same event model but have isolated variables and properties.

When you assign the function to the button.onclick you actually set a handler for the existed event model. (btw, using onlick= is not good practice). But by assigning a function to the .fun - you are creating a new property, which will be isolated from the web page.

Upvotes: 1

Related Questions