我必须提供一个无法修改的外部脚本画布。不幸的是,我稍后必须更换画布,所以我创建了一个简单的可变代理。但是,外部脚本会尝试以我的代理对象作为第二个参数执行insertBefore,并且以某种方式失败。
重现问题(摆脱了可变性以简化一点):
var canvas = new Proxy(document.getElementById("canvas"), {
get: function get(target, property, receiver) {
let originalProperty = target[property]
return typeof originalProperty === "function"
? originalProperty.bind(target)
: originalProperty
},
set: function(target, property, value, receiver) {
target[property] = value
}
})
canvas.parentElement.insertBefore(document.createElement('div'), canvas)
结果:
Uncaught TypeError: Failed to execute 'insertBefore' on 'Node': parameter 2 is not of type 'Node'.
有趣的部分:canvas instanceof Node
返回true
。 typeof canvas
返回"object"
,但typeof document.getElementById("canvas")
也返回。
答案 0 :(得分:1)
解决方案涉及重载 public class Script1 : MonoBehaviour
{
public List<string> testList = new List<string>();
void Start()
{
testList.Add ("Item 1");
testList.Add ("Item 2");
testList.Add ("Item 3");
}
}
public class Script2 : MonoBehaviour
{
Script1 s1;
IEnumerator Start()
{
s1 = GetComponent<Script1>();
yield return new WaitForEndOfFrame();
foreach(string s in s1.testList)
print (s);
}
}
并使用How to get the target of a JavaScript Proxy?中找到的方法
在代理处理程序中,getter为属性Node.prototype.insertBefore
添加了一个条件,以返回原始目标节点。
然后在PROXY_NODE
重载中,检查该属性是否为真,并更改是否为第一个参数
insertBefore
const PROXY_NODE = Symbol('PROXY_NODE');
// Overload Node.prototype.insertBefore
const oldInsertBefore = Node.prototype.insertBefore;
Node.prototype.insertBefore = function(...args) {
if (args[0][PROXY_NODE]) {
args[0] = args[0][PROXY_NODE];
console.log(args[0]);
}
oldInsertBefore.apply(this, args)
}
// proxy handler
const handler = {
get: (target, property, receiver) => {
if (property === PROXY_NODE) {
return target
}
return Reflect.get(target, property, receiver)
},
set: function(target, property, value, receiver) {
target[property] = value
}
}
// Create proxy node
const proxyNode = new Proxy(document.createElement("div"), handler);
// proxy setter is working
proxyNode.textContent = 'Proxy Content';
// insert proxy node
var parentDiv = document.getElementById("parentElement");
var childDiv = document.getElementById("childElement");
parentDiv.insertBefore(proxyNode, childDiv );