$(document).ready(function(){
var _new_li = $('', {
'id': 'p',
'text': 'CLICKME',
click: function(){
alert('fired');
},
data: {
'somedata': 'somedata',
}
});
_new_li.appendTo($("#example"));
});
I receive an "Uncaught TypeError: Cannot read property 'click' of undefined", when I try to click the element which I created like so. But, if you switch click: and data: it works.
$(document).ready(function(){
var _new_li = $('<li/>', {
'id': 'p',
'text': 'CLICKME',
data: {
'somedata': 'somedata',
},
click: function(){
alert('fired');
}
});
_new_li.appendTo($("#example"));
});
any explanation for that behavior?
Kind Regards
--Andy
PS:
I posted a similar behavior earlier in the jQuery Core Development forum, Mr. Swedberg answered there:
I'm pretty sure this is happening because you're setting data with an object, which >(until 1.4.2) would overwrite the event object. Not sure which version of jQuery you're >using in your project, but it looked like the jsbin example was using 1.4. Try upgrading >to 1.4.2 and see if that helps.
But it seems like the problem still exists in 1.4.2
Post rewrited.
You shouldn't put that comma after last (and only) element in data.
After trying some stuff I got to this:
$(document).ready(function(){
var fun=function(){
alert('fired');
};
var parms={
'id': 'p',
'text': 'CLICKME',
'click':fun,
'data': {
'somedata': 'somedata'
}
};
console.log(parms);
var _new_li = $('<li/>',parms);
_new_li.appendTo($("#example"));
});
Everything works fine until I click on the li element. Then I get e is undefined (jquery line 55)
. Works well when click and data are swapped.
Still investigating
AND FOUND IT
jquery development version, line 1919
var events = jQuery.data(this, "events"), handlers = events[ event.type ];
events is undefined.
jquery overwrites events stored in data.
so this IS a bug. It should just extend.
I've submited a bug report.
folks.. this is no bug.. what's happening is that you need to use the event data argument
.click( [ eventData ], handler(eventObject) )
eventDataA map of data that will be passed to the event handler.
to know why that's necessary you can review the discussion in the jquery documentation of .bind().. you may also want to review the concept of "closure" in javascript.. it provides the rationale behind this whole thing
this part is especially relevant (taken from http://api.jquery.com/bind/):
Passing Event Data
The optional eventData parameter is not commonly used. When provided, this argument allows us to pass additional information to the handler. One handy use of this parameter is to work around issues caused by closures. For example, suppose we have two event handlers that both refer to the same external variable:
var message = 'Spoon!';
$('#foo').bind('click', function() {
alert(message);
});
message = 'Not in the face!';
$('#bar').bind('click', function() {
alert(message);
});
Because the handlers are closures that both have message in their environment, both will display the message Not in the face! when triggered. The variable's value has changed. To sidestep this, we can pass the message in using eventData:
var message = 'Spoon!';
$('#foo').bind('click', {msg: message}, function(event) {
alert(event.data.msg);
});
message = 'Not in the face!';
$('#bar').bind('click', {msg: message}, function(event) {
alert(event.data.msg);
});
This time the variable is not referred to directly within the handlers; instead, the variable is passed in by value through eventData, which fixes the value at the time the event is bound. The first handler will now display Spoon! while the second will alert Not in the face!
I ended up modifying the source code slightly, so it would not randomly blow up here.
handle: function( event ) {
...
// tbn modified source
try {
var events = jQuery.data(this, "events"), handlers = events[ event.type ];
} catch(e) {}
// tbn modified source
..then re-minified the source
I have not had any problems with this since (yet).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With