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 shim ( html5shivなど) が必要なようで、HTML5 要素が発生する前にロードする必要があることです (パーサーが混乱しないようにするため)。 )。deferJSBin が自動的に追加する属性は、この動作を中断します。

シムがないと、エレメントがバラバラになります。DOM は次のようになります。

<section/>
My section
</section/>

(IE8 開発ツールに見られるように、少なくともここで働いている解釈の創造性を賞賛する必要があります)

これにより、関連するすべてのセレクターが壊れます (したがって、投稿したJSBin アイテムのテキストが緑色にならないのはこのためです)。他のすべての呼び出し (insert、append など) がまだ機能していた理由は、それらに供給していた html が同じだった (そして同じように誤って解析された) ためです。

解決策は、私が投稿した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 に答える