ラベル jQuery の投稿を表示しています。 すべての投稿を表示
ラベル jQuery の投稿を表示しています。 すべての投稿を表示
2012年6月20日水曜日

jQuery.fn.loadのcallbackで受け取るjQuery.Event.targetはIEでDOM要素をとれない時がある

タイトルで大体言いきりました。

写真のスライドショーを作成していて、画像タグはJavaScript側で作成してDOMに追加するようにしていました。 何故こうしたかというと、環境によって画像の読み込みが終わらないうちにスライドショーの自動再生が始まってしまうのを防ぐためです。

具体的には以下のようなコードで画像の読み込み完了を待ってDOMに追加しています。

$('').attr(src: '/images/hoge.jpg?' + new Date().getTime()).load (e) =>
  $img = $ e.target
  $('#container').append $img

'?' + new Date().getTime() の部分ですが、コレをしておかないとIEがonloadイベントをサボるんですよね。。
必ずイベントを発火させるようにしています。

でIMG要素を $ e.target でjQuery化してappendという流れですが、実はこれだとIEでIMG要素がとれていないんです!
気づかずにそのまま処理を進めると画面真っ白になってお馴染みのわかりづらいエラーメッセージにかなり困惑しました。

IE8で以下の様に検証してみました。

A) e.targetでIMG要素が取得できない

$('').attr(src: '/images/hoge.jpg?' + new Date().getTime()).load (e) =>
  console.log e.target.nodeName # => #document

B) e.targetでIMG要素がとれる

$img = $ 'img.sample'
$img.attr(src: $img.attr('src') + '?' + new Date().getTime()).load (e) =>
  console.log e.target.nodeName # => IMG

違いはJSで要素を作成するか、htmlに記述されている要素を取得するかですね。

まぁぶっちゃけ loadのcallback内でthisが対象のIMG要素なのでコレ使えばいいんですよ。
でもCoffeeScriptつかってclass化したオブジェクトの中だと @(this) は常にクラスそのものとして使いたいので、 関数のthisにバインドしてくれる => を使いたいんですよね。

というわけで jQuery.Event オブジェクトの出番なわけです。
Aの方法だとIEで期待通りでないことがわかったので調べたところ、jQuery.Event.currentTarget というのがありました。
console.log e.currentTarget.nodeName でちゃんとIMGが返ってきたよ〜!

今後調べたいこと

  • $('<img />') と書いた時にブラウザ別に何が行われているのか
  • jQuery.Eventのコンストラクタを読む

追記:

  • jQuery APIの.load()を見たらDeprecatedのタグが付いてたのでbindでも試してみたけど、結果は一緒
2012年5月30日水曜日

jQueryのプラグイン limp と airy を書いた

ひょんなことからjQueryの視覚系プラグインを2つ書きました。

jquery.limp.js

ソースというかデモサイトまるごとgithubにあります。
jquery.limp.js

要素をfixed配置に変えて縦スクロールに対して少し遅れてついてくるというものです。
いわゆるパララックス効果的に使えるんじゃないかと思います。

DEMO

limpという名前はlimpbizkitからとりました。僕の青春です。

jquery.airy.js

こちらもデモサイトまるごとgithubにあります。
jquery.airy.js

要素をabsoluteで配置しておくとフワフワとその場を浮遊するというものです。
こちらは使い道が難しいですね。

DEMO

両者ともcoffeescriptで書いてsinatraでサーブしてるのですが、素のjavascript書くのしんどいですね最近……

2011年11月20日日曜日

jQueryを使用したJavaScriptコーディングスタイル



こんな感じに落ち着いてる。
CoffeeScript覚えるのめんどくさい。