如何在元素更新后维护事件观察

时间:2009-09-21 17:16:12

标签: javascript events prototypejs

我正在开展一个项目,在这个项目中,我会在布局中放置一个带有默认结果集的搜索框,使用从点击事件触发的Prototype。

当设置输出时,该新页面具有自己使用的Javascript,以动态过滤结果。

现在,新的结果集不适用于之前设置的Javascript。

如何通过每次调用新事件来维护持久性事件? 或者这就是我应该做的。

这是一些加载在'loaded_pa​​ge.php'

中的代码
<script language="javascript">
    var o = new Compass_Modal('add_button', 'history');
    var placetabs = new Tabs('tabs', {
        className: 'tab',
        tabStyle: 'tab'
    });
    $$('.add_button').each(function(s, index){
        $(s).observe('click', function(f) {
            loadData();
        });
    });

    function loadData() {
        new Ajax.Request('/sponsors/search', {
            onComplete: function(r) {
                $('overlay').insert({
                    top:'<div id="search_table">'+r.responseText+'</div>'
                });
            }
        })
    }
</script>

然后在通过javascript插入的包含页面中:

    <div id="search_overlay">
    <div id="form_box">
        <a href="javascript:void(null);"><img src="/images/closebox2.png" class="closebox" /></a>
        <form method="post" id="search_form" class="pageopt_left">
            <input type="text" name="search_box" id="search_box" value="search" />  
        </form>
    </div>
    <div id="table_overlay">
        <table class="sortable" id="nf_table" cellpadding="0" border="0" cellspacing="0"> 
<tr> 
<th id="name_th">Name</th><th id="amount_th">Amount</th><th id="tax_letter_th">Tax Letter</th><th id="date_th">Date</th><th id="add_th">Add</th></tr> 
<tr> 
<td>Abramowitz Foundation (The Kenneth & Nira)</td><td><input type="text" name="amount" value="" id="amount_111" /></td><td><input type="checkbox" name="tax_letter" value="1" id="tax_letter_111" /></td><td><input type="text" name="date" value="" id="date_111" /></td><td><a href="http://compass.krd.webhop.net/sponsors/add/111" class="add_button"><img src="/images/icons/add.png" title="add contact" /></a></td></tr> 
... more rows
</table>
    </div>
</div>    
<script language="javascript">
    var c = new Compass_Search('contacts', 'table_overlay');
    c.set_url('/sponsors/sponsor_search');
    $$('.add_button').each(function(s, index) {
        $(s).observe('click', function(e) {
            $(e).stop();

            var params = $(s).href.split("/");
            var userid = params[5];
            var amount = 'amount_'+params[5];
            var date    = 'date_'+params[5];
            var tax     =   'tax_letter_'+params[5];
            if(!Form.Element.present(amount) || !Form.Element.present(date)) {
                alert('your amount or date field is empty ');
            } else {
                var add_params =  {'amount':$F(amount), 'date':$F(date), 'tax':$F(tax), 'id':userid};
                if(isNaN (add_params.amount)) {
                    alert('amount needs to be a number');
                    return false;
                } else {
                    new Ajax.Request('/sponsors/add', {
                        method: 'post',
                        parameters: add_params,
                        onComplete: function(e) {
                            var post = e.responseText;
                            var line = 'amount_'+add_params.id;
                            $(line).up(1).remove();
                        }
                    })
                }
            }
        });
    });

    this.close = $$('.closebox').each(function(s, index) {
        $(s).observe('click', o.unloader.bindAsEventListener(this));
})
</script>

你会在插入的部分注意到一个新的Javascript,它还用新观察者更新了自己的内容。当内容更新时,观察者不起作用。

2 个答案:

答案 0 :(得分:1)

使用活动委派

除了可以替换“观察”元素之外,这种方法还更快更高内存效率

document.observe('click', function(e){
  var el = e.findElement('.add_button');
  if (el) {
    // stop event, optionally
    e.stop();
    // do stuff... `el` now references clicked element
    loadData();
  }
});

答案 1 :(得分:0)

当您调用Element#insert时,我认为应该自动调用String #evalScripts(因为已经查看了这些方法的实现)

也许你可以尝试在Element#observe调用之前做一些console.log()/ alert()消息,看看它出错的地方。这可能是因为根本没有对Javascript进行评估,或者您的代码或类似内容有问题。

作为提示:检查有关Array#invoke的文档,使用该方法可以重写类似的内容:

$$('.add_button').each(function(s, index){
    $(s).observe('click', function(f) {
        loadData();
    });
});

进入这个:

$$('.add_button').invoke('observe', 'click', function(event){
    loadData();
});
// $$('.add_button').invoke('observe', 'click', loadData);