Skip to main content

Bug Tracker

Side navigation

#10556 closed bug (invalid)

Opened October 21, 2011 05:14PM UTC

Closed October 22, 2011 02:56PM UTC

Last modified March 14, 2012 08:11AM UTC

.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.

Attachments (0)
Change History (9)

Changed October 21, 2011 05:28PM UTC by prashantjain68 comment:1

jsFiddle url ....

http://jsfiddle.net/sMByu/

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

Changed October 21, 2011 11:35PM UTC by prashantjain68 comment:2

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.

Changed October 22, 2011 12:20AM UTC by dmethvin comment:3

owner: → 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?

Changed October 22, 2011 12:21AM UTC by dmethvin comment:4

#10555 is a duplicate of this ticket.

Changed October 22, 2011 12:49AM UTC by prashantjain68 comment:5

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

Changed October 22, 2011 02:56PM UTC by dmethvin comment:6

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/

Changed October 22, 2011 05:51PM UTC by prashantjain68 comment:7

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.

Changed October 22, 2011 06:18PM UTC by dmethvin comment:8

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.

Changed October 22, 2011 07:56PM UTC by prashantjain68 comment:9

_comment0: 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 element" approach? 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 \ 1319313494711828

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