代码之家  ›  专栏  ›  技术社区  ›  Freewind thk

通过chrome扩展名向当前页插入按钮,但某些方法不起作用

  •  2
  • Freewind thk  · 技术社区  · 7 年前

    我正在编写一个非常简单的chrome扩展,它在当前页面上添加了一个按钮。

    清单.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"
      ]
    }
    

    弹出式.html

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

    弹出窗口.js

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

    添加按钮.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)
    

    问题

    如果我们单击当前页面的扩展图标,并在浏览器控制台中键入以下代码,这几乎可以很好地工作:

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

    有警报意味着它正在工作。

    但是打电话的时候 fun() 关于:

    button.fun();
    

    它报告这样的错误:

    Uncaught TypeError: button.fun is not a function
    

    不明白为什么 fun 丢失。

    如果需要,还提供一个简单但完整的演示: https://github.com/chrome-demos/chrome-extension-tabs-executescript-add-button-demo


    我在其他答案中看到它说的是内容脚本 run in a "isolated world" ,即页面和内容脚本只能看到相同的DOM,而不能看到彼此定义的变量。令我困惑的问题是,两者都是 onclick 乐趣 是否在DOM上定义了所有函数,为什么它们中只有一个可以很好地工作。

    我猜,代码运行在内容脚本中

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

    定义了两个函数,但它们不被认为是相同的。

    这个 一次点击 是共享DOM的标准属性,因此它直接添加到DOM中,这可以在页面上下文中看到。

    但是 乐趣 方法不是,因此不会添加到共享DOM,而是添加到其他地方(可能是共享DOM的子实例),只需保留在chrome内容脚本的范围内。

    我的猜测正确吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Denis L    7 年前

    你说得对。 网页和内容脚本共享相同的事件模型,但具有独立的变量和属性。

    当您将函数分配给 button.onclick 您实际上为现有的事件模型设置了一个处理程序。 (btw,使用 onlick= 不是很好的做法) . 但是通过将函数赋给 .fun -您正在创建一个新属性,该属性将与网页隔离。