Since as of jQuery 1.7, the .live() method is deprecated, I’ve been trying to convert one of my plugins to use on(), but I keep getting similar errors no matter what I try. The error says, “selection.value is undefined”.
The old code that worked in older versions of jQuery was like this:
/* Monitor events on designated elements */
$(this)
/* Keyup and blur events necessary to handle pasted data */
.live('keyup blur', function() {
/* If a character is being limited */
if (this.value.search(regex) != '-1') {
/* Remove the character from the input */
this.value = this.value.replace(regex, '');
}
})
/* Disable right clicks to prevent pasting via context menu */
.live('contextmenu',function () {return false});
and the new code is like this:
// Hold this in a variable for use in on()
var selection = $(this);
/* Monitor events on designated elements */
$(document)
/* Keyup and blur events necessary to handle pasted data */
.on( 'keyup blur', selection, function() {
/* If a character is being limited */
if (selection.value.search(regex) != '-1') {
/* Remove the character from the input */
selection.value = selection.value.replace(regex, '');
}
})
/* Disable right clicks to prevent pasting via context menu */
.on( 'contextmenu', selection, function () {return false});
I think the selector needs to be a string. But in your case, I don’t know if you need it at all. It looks like you only care about the keyup and blur events on a single element, in which case you can just do this:
$(this).on('keyup blur', function () {
// ...
});
However, if that doesn’t work and you still want to use a selector, I don’t think there’s any simple method that creates a selector for an element on the fly. You’ll have to create one on your own. If, for example, the element has an id…
var selector = '#' + this.id;
$(document).on('keyup blur', selector, function () {
// ...
});
Well, if you are familiar with live(), it was able to attach an event handler to elements that were dynamically created in the future, and that’s essential to some parts of my application. With basic usage of on(), as you suggest in the first example, the attaching only happens to current elements. The code in your second example doesn’t work. If I use console.log() on selector immediately after setting it, it is undefined. This is how the plugin is used by the way:
The problem using a string is that that string is dynamic. Here’s what I did to get it working; I added a second parameter to the plugin function. Instead of calling the plugin using
/* Monitor events on designated elements */
$(document)
/* Keyup and blur events necessary to handle pasted data */
.on( 'keyup blur', element, function() {
/* If a character is being limited */
if (this.value.search(regex) != '-1') {
/* Remove the character from the input */
this.value = this.value.replace(regex, '');
}
})
/* Disable right clicks to prevent pasting via context menu */
.on( 'contextmenu', element, function () {return false});
Any specific reason you’re not using .delegate()?
That also works on both current and future elements, and is more lightweight because it only binds an event to 1 element, instead of binding an element to each and every node it should apply to.
As of jQuery 1.7, .delegate() has been superseded by the .on() method. For earlier versions, however, it remains the most effective means to use event delegation.
So I was thinking it is better to change to on() before delegate is deprecated.
Yes, I’ve tried it that way. If I do that, then the dynamically created form elements throw an error because selection has no value. The solution I came up with above is the only one that works. Just seems like a quick fix and not an elegant solution.