是否可以在JavaScript中侦听对象属性的更改?

Phi*_*ham 23 javascript javascript-events

我正在研究一个主要使用JavaScript构建的网页界面.它基本上是一个(非常)大的形式,有许多部分.每个部分都是基于表单其他部分的选项构建的.每当这些选项更改时,新值将在"注册表"类型对象中记录,其他部分将相应地重新填充.

在许多表单字段上具有事件侦听器开始减慢速度,并且为每个更改刷新整个表单对于用户来说太重/太慢.

我想知道是否有可能将监听器添加到注册表对象的属性而不是表单元素来加快速度?如果是这样,你能提供/指出一些示例代码吗?

更多的信息:

  • 这是jQuery的一个插件,所以我可以从该库中构建的任何功能都会有所帮助,但不是必需的.
  • 我们的用户正在使用IE6/7,Safari和FF2/3,所以如果可能但仅限于"现代"浏览器,我将不得不寻找不同的解决方案.

eye*_*ess 6

据我所知,没有事件触发对象属性更改(编辑:除了,显然,为Object.watch).

为什么不尽可能使用事件委托?也就是说,表单上的事件而不是单个表单元素上的事件,在事件冒出时捕获事件?

例如(我的jQuery生锈了,请原谅我使用Prototype,但我相信你能够轻松地适应它):

$(form).observe('change', function(e) {
    // To identify changed field, in Proto use e.element()
    // but I think in jQuery it's e.target (as it should be)
});
Run Code Online (Sandbox Code Playgroud)

您还可以捕获inputkeyuppaste事件,如果你想让它开火文本字段失去焦点之前.我的解决方案通常是:

  1. 壁虎/基于Webkit的浏览器:观察inputform.
  2. 此外,在基于Webkit的浏览器:观察keyuppaste对事件textareaS(他们不火inputtextarea由于某种原因,S).
  3. IE:观察keyuppasteform
  4. 观察changeform(这触发对selectS).
  5. 对于keyuppaste事件,通过将文本字段value与其比较,将字段的当前值与其默认值(加载页面时的值)进行比较defaultValue

编辑:这是我为防止未经修改的表单提交而开发的示例代码:

通过javascript跟踪表单中的更改的最佳方法是什么?


Phi*_*ham 6

谢谢你的评论.我已经离开了以下内容:

var EntriesRegistry = (function(){

    var instance = null;

    function __constructor() {

        var
            self = this,
            observations = {};

        this.set = function(n,v)
        {
            self[n] = v;

            if( observations[n] )
                for( var i=0; i < observations[n].length; i++ )
                    observations[n][i].apply(null, [v, n]);

        }

        this.get = function(n)
        {
            return self[n];
        }

        this.observe = function(n,f)
        {

            if(observations[n] == undefined)
                observations[n] = [];

            observations[n].push(f);
        }

    }

    return new function(){
        this.getInstance = function(){
            if (instance == null)
            {
                instance = new __constructor();
                instance.constructor = null;
            }
            return instance;
        }
    }
})();

var entries = EntriesRegistry.getInstance();

var test = function(v){ alert(v); };

entries.set('bob', 'meh');

entries.get('bob');

entries.observe('seth', test);

entries.set('seth', 'dave');
Run Code Online (Sandbox Code Playgroud)

接受您的评论,我将在表单对象上使用事件委托来更新注册表并触发已注册的观察方法.

到目前为止,这对我来说效果很好......你们可以看到有什么问题吗?