jQueryで、レスポンシブ対応のライブラリを書いていてハマりました。
<a href="#" class="trigger">クリック</a>
<div class="example" data-height="176">
<p>画面幅によってここの行数が変わる</p>
</div>
雑に書くとこんな感じです。.triggerをクリックすると.exampleが自身の高さを利用した処理を行う、というものです。.exampleの中には長文が入るため、画面幅によって大幅に高さが変動します。
画面幅が変わったときだけカスタムデータ属性を更新しておけば、クリックしたときに最新の高さを調べ直さなくていいよね、と思っていたのですが…
何回やっても、最初に画面をロードしたときの高さが返ってきてしまいます。
h = $('.example').data('height');
// hは常にロードしたときの高さになってしまう
クリックイベントに原因があるのでは…などと散々悩んだのですが、dataメソッドを使用していたからでした。
jQueryのカスタムデータ属性の仕様
jQueryのdataメソッドは、基本的にキャッシュを参照しています。
今回の場合、キャッシュはクリックイベントが作成された時点の内容なので、その後、HTMLの属性値が更新されていても反映されません。
対策
dataメソッドではなく、以下で処理します。
- attrメソッド
- JavaScript本来の関数(getAttribute)
getAttributeなら確実にキャッシュ参照を回避できるようですが、getElementsByClassNameが混ざると処理が複雑になるのでやめました。
素直に、クリックした都度innerHeightで高さを取得していればよかったかもしれません…