我们能覆盖JavaScript DOM对象原型属性吗?

22 浏览
0 Comments

我们能覆盖JavaScript DOM对象原型属性吗?

我一直在寻找一种永久改变HTMLFormElement Javascript对象的'onsubmit'行为的方法。假设我的一个Javascript代码包含以下内容:

HTMLFormElement.prototype.onsubmit = function () {
    this.submit();
    // 确保只能提交一次。
    this.onsubmit = function () {
        return false;
    };
    return false;
};

这个想法是简单地防止文档中所有表单的重复提交。我无法找出如何做到这一点,因为上面的例子不起作用。

有没有办法在文档加载后不循环遍历所有现有的HTMLElement来实现这一点?这种方法将与一些较旧的浏览器兼容,并且如果使用其他脚本创建新的表单元素,行为也将持久存在。(仅使用原生JS)

0
0 Comments

在这段对话中,讨论的问题是如何在所有表单上预定义"onsubmit"动作,而不需要逐个处理每个表单。原因是在使用document.createElement('form')创建新的表单时,需要重新运行下面的代码,但只需对新表单重新运行,而不是所有表单。讨论中提到可以使用事件委托来解决这个问题。然后讨论了事件冒泡和IE9的兼容性问题。最后提到,停止其他事件处理程序才是这个问题的关键,而不是停止表单本身的提交。因为表单提交后页面会重新加载,而且只能提交一次。使用事件委托和阻止默认操作并不能停止直接附加的事件处理程序。但如果表单在新窗口中打开,委托的preventDefault将起作用。如果在使用iframe时,委托事件也是有用的。

解决方法是使用事件委托来预定义"onsubmit"动作,通过捕获而不是冒泡来监听非冒泡事件。在讨论中提到,"submit"事件实际上是冒泡的。对于IE9的兼容性问题,可以使用attachEvent来解决。最后,讨论了如何使用"target"属性来处理表单的提交目标。

0
0 Comments

可以通过在文档上安装一个捕获事件监听器来简单地防止表单重复提交。捕获事件是因为它发生得更早,更不容易通过stopPropagation拦截,而不取消默认操作,这在这种情况下是表单提交。

document.addEventListener("submit", (e) => {e.preventDefault();}, true);

提交事件实际上会向文档传播吗?我认为评论中有人声称它不会,否则那将是理想的解决方案。

顺便说一下,我在Chrome和Firefox上尝试了defineProperty的技巧,它似乎没有按预期工作。我不确定是否实际上有一种方法可以实现我所希望的,而不必经过所有元素。此外,事件监听器的技巧在所有浏览器中都不起作用。

我说原型的东西不是你想要的,我只是先回答了问题的这一部分。

0
0 Comments

可以覆盖JavaScript DOM对象原型属性吗?

在JavaScript中,可以覆盖HTMLElement属性,同样适用于HTMLElement的子类。但是对于某些属性,比如事件回调,是不允许这样做的,因为它们不是普通的属性,而是gettersetter。你的代码会出现下面的错误,这也许是你所说的“不起作用”:

image description

即使你成功这样做了,我也不确定结果行为是否符合标准。我认为这肯定不会在不同浏览器之间保持兼容。

根据我的经验,因为需要特定的功能而全局更改一些API并不是一个好主意 - 很快你的需求可能会改变,你就需要整体改变整个API。

再次关注的是,如果你创建一个新的表单(例如:var newForm= document.createElement('form');),如果你希望该行为在整个站点中是标准的,你将不得不重新应用相同的逻辑。这种行为也非常不侵入性,这就是为什么我正在寻找一些简单的方法。但是感谢你提供的细节,至少我明白了为什么不能覆盖这些属性!

相信我,在回答你要求的问题之前,我经过了深思熟虑。我喜欢说,在编程中,没有什么是不可能的。不幸的是,这并不完全正确。

你可以很容易地创建一个工厂函数来创建form元素并附加监听器,现在你只需要调用该函数而不是document.createElement('form')

是的,我已经有类似的想法了 - 谢谢你的建议!

我也考虑过提议覆盖.createElement。但是还有其他创建元素的方式,比如解析HTML(x.innerHTML = "<form ...";)。所以我得出结论,很难找到一个通用可靠的解决方案。

Zato,你也可以创建一个包装器来实现这个功能。虽然我理解你的观点,你必须预先考虑到创建form元素的所有可能的方式。然而,只有你需要处理这些自定义函数,因为你是唯一对覆盖默认行为感兴趣的人。

我强烈愿意和你打赌,你无法覆盖所有的API 🙂 同样,我对覆盖某些API的性能问题也有一些担忧。这是一个有趣的事情,但绝对不是在严肃的业务中的好主意。

0