Fabrizio Calderan
Fabrizio Calderan

Reputation: 123397

Cloning HTML5 elements and events with jQuery on IE8

I'm trying to clone a HTML5 element with jQuery 1.8.1, but this example jsbin fails on IE<9 (element is not cloned)

Code (simplified)

<head>
  <script src="http://code.jquery.com/jquery-1.8.1.min.js"></script>

  <!--[if lt IE 9]>
     <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
</head>

<body>

  <section>My section</section>
  <button>Clone section</button>
  ...

  <script>
  var section = $('section');
  $('button').on('click', function() {
    var clone = section.clone(true);
    $(clone).insertAfter($('section:last'));
  }); 

  $('section').on('click', function() {
     alert('hey, I am a section');
  }); 
  </script>

</body>

This is, of course, a simplified demo. In my real code I have many nested elements with several events:

My questions

  1. is this a bug of jQuery or did I miss something in my code?

  2. since I'm also cloning the events associated with nodes, which elegant alternative could I use to reproduce the same behaviour of clone() also on IE<9 ?

So far the only workaround I've found is to copy all the nodes via html(), append them via append() and refactor my code taking advantage of event delegation for events associated to those nodes, like so

  $('body').on('click', 'section', function() {
     alert('hey, I am a section');
  }); 

But I'm opened to different ideas: could I use a more elegant/performant/easier/faster approach ?

Thank you.

Upvotes: 4

Views: 1591

Answers (2)

Gijs
Gijs

Reputation: 5262

I guess after all the comments, I might as well add this as an answer: the problem seems to be that you need an html5 shim (like html5shiv), and it needs to be loaded before your HTML5 elements occur (lest the parser get confused). The defer attributes JSBin automatically adds break this behaviour.

Without the shim, the elements get broken up. the DOM ends up looking like this:

<section/>
My section
</section/>

(as seen in the IE8 dev tools -- you've got to at least admire the creativity in interpretation that's at work here)

This breaks all the relevant selectors (hence why the text isn't green in the JSBin item you posted). The reason all the other calls (insert, append, etc.) were still working is that the html you were feeding those was the same (and would get mis-parsed in the same way).

The solution is forcing the shim to load completely before your elements occur, as seen in the jsFiddle counterexample I posted.

Hopefully this solves your issue. I filed a JSBin issue regarding the problems caused by the defer attributes.

Update: this should be fixed in jsbin by now.

Upvotes: 4

Aman J
Aman J

Reputation: 1855

Hi I think the problem really is with <section> ,IE8 is unable to understand it, I have tried Cloning Button and the code runs smoothly :-)

I have tried changing your JavaScript to make it run on IE9:(NOT WORKING FOR < IE9)

<script>
  var section = $('section');
  $('button').on('click', function() {
    var clone = section.clone(true);
    $(clone).insertBefore($('section:last'));  //CHANGE From insertAfter to InsertBefore
  }); 

  $('section').on('click', function() {
     alert('hey, I am a section');
  }); 
  </script>

Now it looks like working for IE9, and other browsers as well.

or if you are specific about placing newly clones Script would be changed as below :

var section = $('section');
var button = $('button')
$('button').on('click', function() {
    var clone = section.clone(true);
    console.log(clone);
  $(clone).insertBefore($('button'));
}); 
$('section').on('click', function() {
  alert('hey, I am a section');
}); 

Upvotes: -1

Related Questions