4

我正在尝试使用 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. 因为我也在克隆与节点关联的事件,我可以使用哪种优雅的替代方法来重现同样clone()在 IE<9 上的相同行为?

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

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

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

谢谢你。

4

2 回答 2

4

我想在所有评论之后,我不妨将其添加为答案:问题似乎是您需要一个 html5 垫片(如html5shiv),并且需要在您的 HTML5 元素出现之前加载它(以免解析器感到困惑)。deferJSBin 自动添加的属性打破了这种行为。

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

<section/>
My section
</section/>

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

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

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

希望这可以解决您的问题。我提交了一个关于由 defer 属性引起的问题的 JSBin 问题

更新:这现在应该在 jsbin 中修复。

于 2012-09-10T13:27:46.697 回答
-1

嗨,我认为问题确实出在<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');
}); 
于 2012-09-10T12:10:35.977 回答