我们可以覆盖 Javascript DOM 对象原型属性吗?

Nic*_*tte 3 html javascript dom ecmascript-5 ecmascript-6

我一直在寻找一种方法来永久更改 HTMLFormElement Javascript 对象的“onsubmit”行为。假设我的 JavaScript 之一包含以下代码:

HTMLFormElement.prototype.onsubmit = function () {
    this.submit();
    // Make sure that you can only submit once.
    this.onsubmit = function () {
        return false;
    };
    return false;
};
Run Code Online (Sandbox Code Playgroud)

这个想法只是为了防止所有形式的文档的重复提交。由于上面的示例不起作用,我无法弄清楚如何执行此操作。

有没有办法在文档加载后无需循环遍历所有现有 HTMLElement 来实现此目的?这是一种与某些较旧的浏览器兼容的方法,并且如果您使用其他脚本创建新的表单元素,也可以保留该行为。(仅限香草 JS)

the*_*472 5

我们可以覆盖 Javascript DOM 对象原型属性吗?

尽管 javascript 规范削减了主机对象,但在违反正常 javascript 行为方面Object.defineProperty(HTMLFormElement.prototype, "onsubmit", {get: () => {return false;}})确实发挥了作用。“工作”就像在原型上设置吸气剂一样。

但这实际上并不是您想要的。这只是替换 getter/setter 功能。无法保证浏览器会通过 javascript 继承链来检索当前表单的处理程序。

要么是因为它通过直接查看一些底层本机属性来绕过 javascript,要么是因为它根本不必查看原型并查看表单本身的实例属性。

如果您不知道目标类实际如何以及何时使用各个属性,那么弄乱原型很少是一个好主意。

另一件事: getter/setter 实际上是 on HTMLElement.prototype,而不是HTMLFormElement.prototype。至少 Firefox 是这样。在尝试搞乱继承链之前,您至少应该检查它;)

这个想法只是为了防止所有形式的文档的重复提交。

您只需在文档上安装捕获事件侦听器即可,而不必弄乱原型。

捕获,因为它发生得更早,并且不太可能在不取消默认操作(本例中是表单提交)的情况下通过stopPropagation拦截。

document.addEventListener("submit", (e) => {e.preventDefault();}, true);
Run Code Online (Sandbox Code Playgroud)