如何通过javascript删除keyup事件监听器

时间:2011-09-22 13:31:43

标签: javascript events google-search-api

我在文字字段中使用Google自动填充API在您输入时建议位置。 我遇到的主要问题是Google不允许您将结果限制在特定国家/地区,它只是让您将结果偏向区域范围,这是无用的。

因此,即使您所在的地区设在欧洲的某个地方,对"ru"这个词进行搜索也会为您提供建议。

我意识到,如果你举例如“法国茹”它会给你法国地点只匹配ru是完美的。

所以我的问题是自动填充完全由google javascript构建。

autocomplete = new google.maps.places.Autocomplete(input, options);

所以我不能轻易地用搜索字符串来添加"france"

我可以看到该字段上onkeyup事件绑定的内容并且可以自己调用它,但是我无法将其与keyup取消绑定。我尝试了几种解决方案,但是找不到办法。 jQuery unbind将不起作用,因为这显然不是通过它绑定的。本机函数需要引用函数绑定到侦听器,但这是其中的匿名函数。找到一些使用element.data['events']上的循环的示例,但我得到数据未定义错误。

有没有解决方案解除onkeyup中注册的所有内容?

2 个答案:

答案 0 :(得分:0)

你提到了jQuery,所以我会用它:

$(input).data('events').keyup是包含所有keyup处理程序的数组。如果Autocomplete只使用一个keyup事件,你可以劫持处理程序,先运行你需要的任何函数,然后运行原始函数:

var originalKeyup = $(input).data('events').keyup[0].handler;
$(input).data('events').keyup[0].handler = function(){
    // your code here, where you can add 'france' to input.value

    // fire the old function
    originalKeyup.apply(this,arguments);
};

您也可以从keyup数组中删除原始事件处理程序,并绑定可以执行所需操作的新事件处理程序。


更新: 您可以劫持Element.prototype.addEventListener(BEFORE ALL OTHER CODE)以向Element添加events属性,该属性将包含由任何代码添加的任何处理程序:

var oldAddEventListener = Element.prototype.addEventListener || Element.prototype.attachEvent;
Element.prototype.addEventListener = Element.prototype.attachEvent = function(type, handler){
    this.events = this.events || {};
    this.events[type] = this.events[type] || [];
    this.events[type].push({handler: handler})
    oldAddEventListener.apply(this,arguments);
};

现在,每次通过jQuery或其他方式调用addEventListener时,都应该使用当前事件更新Element的events属性。您可能还希望在调用removeEventListener时劫持events以从removeEventListener对象中删除相应的事件:

var oldREL = Element.prototype.removeEventListener || Element.prototype.detachEvent;
Element.prototype.removeEventListener = Element.prototype.detachEvent = function(type, handler){
    this.oldREL.apply(this,arguments);
    if(this.events && this.events[type]){
        for(var i=this.events[type].length-1; i>=0; i--){
            if(this.events[type][i].handler == handler){
                this.events[type].splice(i,1);
                break; // remove only the first occurrence from the end
            }
        }
        if(this.events[type].length==0){
            delete this.events[type];
        }
    }

};

现在您应该能够检查在任何元素上注册的所有事件。您可以通过迭代'keyup'对象并使用input.events.keyup来删除所有input.removeEventListener个事件。

IE< 9使用attachEventdetachEvent。我没有IE,所以它没有在那里测试过。它在Safari 5中运行良好。如果您在其他浏览器中遇到问题,请告诉我。

注意:在页面上执行任何其他代码之前,需要使用这些mod。


更新: 显然,这在FF或Opera中不起作用。在代码中将Element更改为HTMLInputElement将解决问题。

答案 1 :(得分:0)

您是否尝试将自动填充功能绑定到当前地图范围as shown in the documentationautocomplete.bindTo('bounds', map)