在IE8上使用jQuery克隆HTML5元素和事件

Cloning HTML5 elements and events with jQuery on IE8

本文关键字:HTML5 元素 事件 克隆 jQuery IE8      更新时间:2023-09-26

我正在尝试使用 jQuery 1.8.1 克隆 HTML5 元素,但此示例 jsbin 在 IE<9 上失败(元素未克隆(

代码(简体(

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

当然,这是一个简化的演示。在我的真实代码中,我有许多嵌套元素,其中包含几个事件:

我的问题

  1. 这是jQuery的错误还是我在代码中遗漏了某些内容?

  2. 因为我也在克隆与节点关联的事件,所以我可以使用哪种优雅的替代方案来重现 IE<9 上相同的clone()行为?

到目前为止,我发现的唯一解决方法是通过html()复制所有节点,通过append()附加它们,并利用与这些节点关联的事件的事件委托重构我的代码,如下所示

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

但我对不同的想法持开放态度:我可以使用更优雅/高性能/更容易/更快的方法吗?

谢谢。

我想

在所有评论之后,我不妨添加这个作为答案:问题似乎是你需要一个html5填充程序(如html5shiv(,并且它需要在HTML5元素出现之前加载(以免解析器混淆(。JSBin 自动添加的defer属性会破坏此行为。

没有垫片,元素就会被分解。 DOM 最终看起来像这样:

<section/>
My section
</section/>

(正如在IE8开发工具中看到的那样 - 你至少必须钦佩这里工作的解释创造力(

这会破坏所有相关的选择器(因此,您发布的 JSBin 项中的文本不是绿色(。所有其他调用(插入、追加等(仍在工作的原因是,您输入的 html 是相同的(并且会以相同的方式被错误解析(。

解决方案是强制填充程序在您的元素出现之前完全加载,如我发布的 jsFiddle 反例所示。

希望这可以解决您的问题。我就延迟属性引起的问题提交了 JSBin 问题。

更新:现在应该在 jsbin 中修复此问题。

嗨,

我认为问题确实出在<section>上,IE8无法理解它,我尝试过克隆按钮并且代码运行流畅:-(

我尝试更改您的JavaScript以使其在IE9上运行:(不适用于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>

现在它看起来也适用于IE9和其他浏览器。

或者,如果您特定于放置新克隆,脚本将更改如下:

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');
});