Bug Tracker

Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#10556 closed bug (invalid)

.live() + .trigger("change") throws a run time error

Reported by: prashantjain68 Owned by: prashantjain68
Priority: undecided Milestone: None
Component: unfiled Version: 1.6.4
Keywords: Cc:
Blocked by: Blocking:

Description

I have an element which is not added to the DOM. An event handler has been attached via .live(). The element dispatches a change event via trigger() and I get the following error ...

<DocumentFragment> has no method getAttribute.

Sample source code ... <html>

<head>

<script type="text/javascript" src="jquery.js"></script> <script>

$(document).ready(function() {

jQuery("[groupId='hobbies']").live("change", myHandler); var $checkbox = $("<input type='checkbox' groupId='hobbies'/>"); $checkbox.trigger("change");

});

function myHandler() { }

</script>

</head>

<body> </body>

</html>

NOTE: I do not get an error If this checkbox was appended to the DOM.

Change History (9)

comment:1 Changed 8 years ago by prashantjain68

jsFiddle url .... http://jsfiddle.net/sMByu/

I used chrome and dev tools will show the error I mentioned.

comment:2 Changed 8 years ago by prashantjain68

The problem is in the function ...

ATTR: function( elem, match ) {

var name = match[1],

result = Expr.attrHandle[ name ] ?

Expr.attrHandle[ name ]( elem ) : elem[ name ] != null ?

elem[ name ] : elem.getAttribute( name ),

.... .... ....

}

replacing "elem.getAttribute( name )" with "elem.getAttribute ? elem.getAttribute( name ) : undefined" would fix the issue.

comment:3 Changed 8 years ago by dmethvin

Owner: set to prashantjain68
Status: newpending

Since .live() depends on having the element attached to the document, the event dispatch won't work. Are you saying you don't care that the event handler doesn't work but just don't want to see the error? Can you create an example in jsFiddle showing what you want to do?

comment:4 Changed 8 years ago by dmethvin

#10555 is a duplicate of this ticket.

comment:5 Changed 8 years ago by prashantjain68

Status: pendingnew

dmethvin, Thanks for the quick response. I have modified the example and here is the new jsFiddle url. http://jsfiddle.net/sMByu/4/

In the above example, I have 2 checkboxes, 1 attached to the document and 1 not. I also modified the jquery code on my local machine to check for "elem.getAttribute" before calling "elem.getAttribute( name )". The results are ... 1) No run time exception. 2) jQuery invoked the handler for both the attached and non-attached checkboxes.

In short, the solution I provided works.

Thanks

comment:6 Changed 8 years ago by dmethvin

Resolution: invalid
Status: newclosed

The jsFiddle confirms the code is trying to trigger .live() on an element not in the document. That cannot work, since the event must bubble to the document and it cannot since the elements are not there. The error you are receiving is a futile cry for help from the jQuery API, attempting in its own way to point this out.

In short, the solution I provided works.

Works in that it eliminates the error, or in that it somehow allows a detached element to use .live()? Certainly not the latter. Note that your handler is not called, even though the jquery-git version does not report an error:

http://jsfiddle.net/sMByu/9/

comment:7 Changed 8 years ago by prashantjain68

dmethvin, I checked your example. You have used a jquery-git version and I am not sure what are the differences between the 1.6.4 version and the git version.

Check this jsfiddle. All I have done is made one change which is mentioned above in one of my comments. I have modified the jsfiddle to include the modified jquery-1.6.4 from my domain and do an alert. The error is eliminated, the triggered change is handled by the .live() and invokes the handler. I would appreciate if you could explain me why do you sa "Certainly not the latter". All I am saying is check whether the elem has the getAttribute method before calling it. http://jsfiddle.net/sMByu/12/

I am not developing an application, I am developing a framework which I plan to open source hence I have to make sure this is fixed in jquery.

comment:8 Changed 8 years ago by dmethvin

Please do not use .live() at all in any new work, it is confusing because the event handler is implicitly attached at document. Again, the problem isn't the error that is occurring, it's a mistaken assumption that .live() should work on disconnected elements. The example is not valid usage of the API, so it is not supposed to "work" -- whether it generates an error or not.

Most likely the reason your example "works" in 1.6.4 is bug #10489 which is fixed in 1.7. Event delegation with .live() and .delegate() depends on the event bubbling, and elements won't (shouldn't) bubble to document out of a disconnected element/subtree. The jQuery-git.js test works as intended.

comment:9 Changed 8 years ago by prashantjain68

Got it. Thanks Dave.

The "non-disconnected element" might be the right approach but might be limiting too. Here is a use case why I think it might be limiting.

I have a view called MyView (which is a js object, a wrapper for html elements). I would expose properties like "selected". The MyView will contain a checkbox and other elements. In a typical Ajax application where we manipulate the DOM, an instance of MyView could be in a detached/disconnected state. But we could set the myView.selected = true. This should select the checkbox in the myView instance and because this is programatic changing the checkbox.checked property, we need to dispatch a "change" event. There might be a .live() or .delegate() listening to these "change" events and updating the model. How does the "non-disconnected element" approach help in this case?

In todays Ajax world, DOM manipulation and elements living or not living on the DOM is very very common. I have many use cases that will fail because of the "non-disconnected element" approach. Is jQuery good only for the non-disconnected elements? I request the jquery team to throughly think through this before tying this framework to the non-disconnected approach.

Meanwhile, I will have to look for a different approach to solve my problem. I could have piggy backed on jquery's .is() and .closest() methods but unfortunately they call the Sizzle.selectors.filter.ATTR which does not check for elem.getAttribute before invoking it. Any chances of doing a check before calling getAttribute (developers are innovative and will find many different ways to use a framework).

Thanks

Last edited 8 years ago by prashantjain68 (previous) (diff)
Note: See TracTickets for help on using tickets.