首页 > 解决方案 > 如何替换 Element 原型方法?

问题描述

我应该怎么做才能使它在greasemonkey中工作?:

Element.prototype._attachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function () {
    return this._attachShadow( { mode: "open" } );
};

现在,当我使用这个时: document.body.attachShadow({mode:"closed"}).innerHTML = "dec";

这是错误吗:

错误:访问对象的权限被拒绝

我应该怎么做才能使应用程序使用替代方法?

编辑(更多信息):

Firefox Nightly 62.0a1 (2018-06-18) (64 位)

Greasemonkey 4.4.0

// ==UserScript==
// @name     Unnamed Script 124585
// @version  1
// @grant    none
// @include http://kind-clarke-ced7cb.bitballoon.com/
// ==/UserScript==


Element.prototype._attachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function () {
    return this._attachShadow( { mode: "open" } );
};
console.log("US work");

测试页面: http: //kind-clarke-ced7cb.bitballoon.com/

<div id="test" style="border: 1px solid silver;">xxx</div>

<div id="info">wait 4 sec...(so that UserScript can load itself before)</div>
   <script>
setTimeout(()=>{
  document.querySelector("#test").attachShadow({mode:"closed"}).innerHTML = "dec";
  document.querySelector("#info").innerHTML += `<br/>run: document.querySelector("#test").attachShadow({mode:"closed"}).innerHTML = "dec";`;
}, 3000);

setTimeout(()=>{
  document.querySelector("#info").innerHTML += `<br/>shadowRoot of #test is: ${(document.querySelector("#test").shadowRoot)}`;
}, 4000);
    </script>

现在,attachShadow 方法的这种替换根本不起作用。

#test 的 shadowRoot 返回 null 但应该是[object ShadowRoot],因为 UserScript 强制它。

标签: firefoxgreasemonkey-4

解决方案


shadowdomFF 版本 59 开始默认禁用。要启用它,需要修改首选项。

转到about:config-> 搜索dom.webcomponents.shadowdom.enabled-> 双击它以切换布尔值(将其设置为true) -> 重新加载您的页面。

MDN 文档供参考

现在替换将起作用。经测试Firefox Quantum 60.0.2 (64 bit)Firefox Nightly 62.0a1 (64 bit)

但是在通过检查时在 HTML 树中看不到阴影元素Inspect ElementBugZilla中也报告了一个错误

只有一条信息消息说明Shadow DOM used in [site-link] or in some of its subdocuments.将记录在控制台中。(消息仅在 Nightly 版本中显示)

编辑: 经过一番挖掘,发现使用unsafeWindow可以解决您的问题。关于 unsafeWindow 的小细节

// ==UserScript==
// @name     Unnamed Script 124585
// @version  1
// @grant    none
// @include  http://kind-clarke-ced7cb.bitballoon.com/
// ==/UserScript==

unsafeWindow.Element.prototype._attachShadow = unsafeWindow.Element.prototype.attachShadow;
unsafeWindow.Element.prototype.attachShadow = function () {
    return this._attachShadow( { mode: "open" } );
};
console.log("US work");
setTimeout(()=>{
  document.querySelector("#test").attachShadow({mode:"open"}).innerHTML = "dec";
  document.querySelector("#info").innerHTML += `<br/>run: document.querySelector("#test").attachShadow({mode:"closed"}).innerHTML = "dec";`;
}, 1000);

setTimeout(()=>{
    document.querySelector("#info").innerHTML += `<br/>shadowRoot of #test is: ${(document.querySelector("#test").shadowRoot)}`;
}, 2000);

替换没有按原样mode工作closed。将其更改为open.


推荐阅读