在不太详细地解释我正在处理的项目细节的情况下,我试图确定一种方式,可以在访问document.getElementById().value时实现一个事件侦听器,或者以类似于对象的方式重写它,并为获取和设置该值定义自定义行为.这可能吗?

我试过以下方法,但没有成功:

Object.defineProperty(document.getElementById, 'nodeValue', {
    get: function () {
        console.log('document.getElementById value accessed');
        return this.nodeValue;
    },
    set: function (value) {
        console.log('document.getElementById value set');
        this.nodeValue = value;
    }
});

与上面相同,但用value代替nodeValue:

Object.defineProperty(document.getElementById, 'value', {
    get: function () {
        console.log('document.getElementById value accessed');
        return this.value;
    },
    set: function (value) {
        console.log('document.getElementById value set');
        this.value = value;
    }
});

抱歉如果这看起来有点牵强,那么JavaScript背后的复杂性我并不太熟悉.然而,上面的代码说明了我想要实现的目标.我只是不知道怎么做!

我花了一些时间研究MDN,试图了解它是如何工作的,从我收集到的信息来看,getElementById()返回一个元素,该元素继承自包含nodeValue的 node 接口,我认为这个nodeValue是我感兴趣的,但我不能确定.

编辑:我希望这种行为是通用的,我有不止一个(但数量未知)元素,所以我不试图将其应用于特定元素.

推荐答案

首先,修改Element个对象是个坏主意.扩展它是不好的,但没有修改它那么糟糕.这是因为,web浏览器上的JavaScript实现没有详细说明底层API的工作方式.例如

1. Modify Element Object

我们有一份文件如下:

<div>
  <h1 id="elem-id">Header Content</h1>
</div>

我们可以通过调用这些指令来获得它的id

let elem = document.getElementById('elem-id');
elem.getAttribute('id'); // 'elem-id';

我们可以使用以下方法修改getAttribute():

Element.prototype.getAttribute = function (attributeKey) {
// Implement your own function here
return 'ok';
}

接下来,当你拨打elem.getAttribute('id')时,它应该返回ok.

这很糟糕,因为没有办法恢复到默认实现.

2. Extending Element Object

其次是扩展对象.我们可以简单地做到:

Element.prototype.getAttributeAndFireEvent = function (attributeKey) {
  console.log(`getting attribute for ${attributeKey}`); // Could be an eventEmitter
  return this.getAttribute(attributeKey);
}

然后,我们可以通过如下方式使用这些方法:

elem.getAttributeAndFireEvent('elem-id');

这将起作用,但在修改全局对象时请小心,它可能会造成意外影响.

参考资料:

  1. In Javascript, can you extend the DOM?

Javascript相关问答推荐

如何解决chrome—extension代码中的错误,它会实时覆盖google—meet的面部图像?'

Spring boot JSON解析错误:意外字符错误

有没有可能使滑动img动画以更快的速度连续?

在服务器上放置了Create Reaction App Build之后的空白页面

在拖放时阻止文件打开

我怎么在JS里连续加2个骰子的和呢?

如何修复我的数据表,以使stateSave正常工作?

将内容大小设置为剩余可用空间,但如果需要,可在div上显示滚动条

我正在试着做一个TicTacToe Ai来和我玩.但是,我试着在第一个方块被点击时出现一个X,然后在第二个方块之后出现一个O

用Reaction-RT-Chart创建实时条形图

在HTML5画布上下文中使用putImageData时,重载解析失败

如何压缩图像并将其编码为文本?

JavaScript:多个图像错误处理程序

如何在加载页面时使锚定标记成为焦点

Refine.dev从不同的表取多条记录

如何阻止外部脚本进入顶层导航

由于http.get,*ngIf的延迟很大

递归地将JSON对象的内容上移一级

CSS网格使页面自动滚动

App Script如何读取通过云函数传递的表单对象