开发者

how to remove keyup event listeners by javascript

开发者 https://www.devze.com 2023-04-06 13:00 出处:网络
I\'m using the Google autocomplete api on a text field to suggest locations as you type. The main problem I have with this is that Google does not let you limit results to a specific country, it just

I'm using the Google autocomplete api on a text field to suggest locations as you type. The main problem I have with this is that Google does not let you limit results to a specific country, it just lets you bias results to area bounds which is kind of useless.

So seaching for term "ru" will give you Russia in suggestions even your region is set to somewhere in Europe.

I realized though that if you put for example "france ru" it gives you france locations only matching ru which is perfect.

So my problem is that the autocomple is completely built by google javascript.

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

So I cannot easily fiddle with search string to add in to it constantly "france"

I can see what is bound to the onkeyup event on that field and can take it and call it myself however I cannot unbind it from keyup. I tried several solutions how to do it but can't find a way. jQuery unbind won't work as this is not bound through it obviously. Native functions want a reference to a function bind to listener but this is annonymous function in it. Found some examples using loops over element.data['events'] but I get data undefined error.

Has anyone solution to unbin开发者_StackOverflow中文版d all what is register in onkeyup ?


You mentioned jQuery, so I'll use that:

$(input).data('events').keyup is the array that will contain all the keyup handlers. If there is only one keyup event used by Autocomplete, you can hijack the handler to first run whatever function you need, then run the original:

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);
};

You could also just remove the original event handler from the keyup array, and bind new ones that will do what you want.


UPDATE: You could hijack Element.prototype.addEventListener (BEFORE ALL OTHER CODE) to add an events property to the Element which will contain any handlers added by any code:

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);
};

Now, every time addEventListener is called, by jQuery or otherwise, the Element's events property should be updated with the current events. You may also want to hijack removeEventListener to remove the corresponding event from the events object when removeEventListener is called:

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];
        }
    }

};

Now you should be able to inspect all events registered on any element. You can remove all 'keyup' events by iterating over the input.events.keyup object and using input.removeEventListener.

The attachEvent and detachEvent are used by IE<9. I don't have IE, so it hasn't been tested there. It works well in Safari 5. Let me know if you have issues in other browsers.

NOTE: These mods need to be in place BEFORE any other code is executed on the page.


Update: Apparently, this will not work in FF or Opera. Changing Element to HTMLInputElement in the code will fix the problem.


Have you tried binding the autocomplete to the current map bounds, as shown in the documentation: autocomplete.bindTo('bounds', map) ?

0

精彩评论

暂无评论...
验证码 换一张
取 消