我有一个本地测试环境,我想在其中临时覆盖querySelector。我知道猴子补丁是不好的做法,但在这种情况下,此代码将仅在开发人员本地使用。我写了这个片段(覆盖 querySelector 以使用选择器中名为 addonID 的另一个子字符串来获取所有选择器):
function maybeOverrideForTestStart(partialIDOfWidget, fullIDOfWidget) {
if(!isLocal) return;
const addonID = fullIDOfWidget.replace(partialIDOfWidget, "");
Element.prototype.querySelectorTemp = Element.prototype.querySelector.bind(Element);
Element.prototype.querySelector = function(selector) {
const element = this.querySelectorTemp(selector);
if (element) return element;
if (addonID) {
return this.querySelectorTemp(selector + addonID) || null;
}
};
}
function maybeOverrideForTestEnd() {
if(!isLocal) return;
Element.prototype.querySelector = Element.querySelectorTemp;
}
我在测试开始时调用
maybeOverrideForTestStart
,在测试结束时调用 maybeOverrideForTestEnd
。但这不起作用,而且我不确定我错过了什么。我得到的是 someElement.querySelector is not a function
或 "Uncaught TypeError: Illegal invocation"
。
注意 - 我也无法理解这是否也覆盖了 document.querySelector 和 document.body.querySelector 或者只是 someElement.querySelector。
感谢帮助,谢谢。
我不确定您是否需要
.bind()
该函数,但您可以在常量中保留对原始函数的引用,例如
const querySelector = Element.prototype.querySelector;
function maybeOverrideForTestStart(partialIDOfWidget, fullIDOfWidget) {
// ....
Element.prototype.querySelector = function (selector) {
const element = querySelector(selector);
if (element) return element;
if (addonID) {
return querySelectorTemp(selector + addonID) || null;
}
};
}
function maybeOverrideForTestEnd() {
// ...
Element.prototype.querySelector = querySelector;
}