accessing stored documentFragments from jQuery's .data method in IE throwing js error

accessing stored documentFragments from jQuery's .data method in IE throwing js error

Hi,

This is probably a super edge case situation (and pretty tough to explain) so please bear with me. :D

Basically I'm trying to load up a cached documentFragment (stored in jQuery's data obj) that contains DOM elements. In IE, after the second time they are appended to a div element, I am getting a javascript error in jquery-1.4.2.js:

Line 4519
Error: 'events' is null or not an object

So I got rid of the error by changing that line from:
  1. if ( data.events ) {
to:
  1. if ( typeof data != 'undefined' && data.events ) {
The only problem now is that my click event handlers on the stored dom elements inside the documentFragment (that were set by .live() in my script's init method) have disappeared.

Here's some more details on how I'm setting up the elements' click event handler, building and storing the documentFragments, and retrieving/appending them:

script init:
  1. var mainobj = {
  2.   fragment_cache: {} // used to store documentFragments
  3. };

  4. // #list is an empty div that will contain several anchor tags w/ the class 'button genre'
  5. $('#list').live('click', function(e) {
  6.   if($(e.target).is('.button.genre') && $(e.target).data('rowData')) {
  7.     alert('clicked it!');
  8.   });
  9. }

building and storing the documentFragments from an xml result:
  1. var genres_list = document.createDocumentFragment();
  2. $(xmlData).find("Genre").each(function(i, node) {
  3.   var $node = $(node), stations = [];
  4.   $(node).find('Station').each(function(i, station) {
  5.     stations.push({ 'id':$(station).find('StationID:first').text(),
  6.       'name':$(station).find('StationName:first').text(),
  7.       'slogan':$(station).find('StationSlogan:first').text()
  8.     });
  9.   });
  10.   genres_list.appendChild( $('<a></a>').addClass('button genre')
  11.     .attr('href', 'javascript:void(0)')
  12.     .html( $node.find('GenreName:first').text() )
  13.     .data('rowData', { 'id': $node.find('GenreID:first').text(), 'stations': stations }).get(0)
  14.   );
  15. });

  16. // store a local copy of this document fragment in the fragment cache for speedy re-use later on
  17. $(mainobj.fragment_cache).data('test', { 'fragment': genres_list.cloneNode(true) });

  18. // display the fragment by appending it to the list div
  19. $('#list').empty().append(genres_list.cloneNode(true));


retrieving and displaying the stored documentFragment:
  1. function loadFrag() {
  2.   if(!$(mainobj.fragment_cache).data('test'))
  3.     return;
  4.   // the following works on every call in chrome, but only twice in IE, after that, the js error above is thrown
  5.   $('#list').empty().append(
  6.     $(mainobj.fragment_cache).data('test').fragment.cloneNode(true)
  7.   ).hide().fadeIn();
  8. }

I suspect it's something to do with .empty() clearing out my .live handlers... but I'm pretty stumped as to why it would only happen after calling loadFrag() for the third time, and especially why only in IE. Well the "only in IE" part doesn't surprise me, haha.

I was thinking of trying to wrap the documentFragment in jQuery closure before i store it, to  see if that made any difference, but I would be super grateful for any ideas or things to try.

Thanks a ton!
-Taber



    • Topic Participants

    • taber