要素のリサイズイベントを検出する jQuery exResize
ブラウザのウィンドウサイズが変更された時に、何らかの処理を行いたい場合、jQuery では resize() メソッドで window オブジェクトに対し処理を割り当てます。
$( window ).resize(function(){ /* 行ないたい処理 */ });
一方、div 要素などの普通の HTML 要素に対し、resize() メソッドで割り当てた処理は起動されることはありません。resize() メソッドではウィンドウのサイズ変更しか検出することができないようです。
今回作成した jQuery プラグイン exResize を使用すると、div 要素等の普通の HTML 要素においても、サイズ変更を検出し、割り当てた処理を実行させることができるようになります。
機能概要
以下の基本機能があります。
- div 要素等の普通の HTML 要素に対するリサイズイベントの割り当て
- 指定要素が内包する要素郡の外周に対するリサイズイベントの割り当て
div 要素等の普通の HTML 要素に対するリサイズイベントの割り当て
resize() メソッドと同様に、サイズ変更を検出したい要素に対し、以下のように処理を割り当てます。
$('div.example').exResize(function(){ /* 行ないたい処理 */ });
以下に使用サンプルを用意しました。
TODO リストのラップ要素に対し、リサイズイベントを割り当ててあります。TODO リストの追加・削除により発生するリサイズイベントにて、変更後の幅と高さを表示するようにしています。
指定要素が内包する要素郡の外周に対するリサイズイベントの割り当て
指定要素が内包する要素郡の外周とは、以下の部分を指します。
contentsWatch パラメータを true にして処理を割り当てると、外周部分のリサイズを検出し、割り当てた処理が起動されるようになります。
$('div.example').exResize({ contentsWatch : true, callback : function(){ /* 行ないたい処理 */ } });
使い道としては、固定サイズの要素における内包要素の伸縮に応じたサイズ調整などが考えられます。
TODO リストのリサイズが発生する都度、固定サイズにしたラップ要素に対し、animate() メソッドによるサイズ調整を行なっています。
使い方
jquery.js、jquery.exresize.js を読み込みます。
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.exresize.js"></script>
基本的な使い方は前述の通りです。
API オブジェクトの利用
API オブジェクトは callback 関数の第1引数より受け取ることができます。API オブジェクトを利用すると、リサイズ監視対象の各種情報を参照することができます。下記の処理ではリサイズ時の内包要素の外周の幅と高さを参照してます。
$('div').exResize({ contentsWatch : true, callback : function( api ){ var size = api.getSize(); alert(size.width); alert(size.height); }; });
api パラメータを true にすると exAPI ベースな API オブジェクトが取得できます。exAPI で生成された API オブジェクトは jQuery オブジェクトのように扱うことができます。下記例では、複数のカラム要素のそれぞれの高さを each() メソッドで求めた後、一番大きいサイズですべての要素の高さを揃えています。
var api = $('div.column-a,div.column-b').exResize({ //api オブジェクトの返却を指定 api : true, callback : function(){ var max = 0; //最大の高さを取得 api.each(function(){ var h = this.getSize().height; max = h > max ? h : max; }); //div.column-a,div.column-b を取得し、高さを一括指定 api.getTargets().height(max); }; });
jQuery exAPI の詳細は以下をご覧下さい。
利用例
高さが伸縮する固定ヘッダーコンテンツに対し、メインコンテンツの表示位置を調整する
IE6 でも position:fixed を行なえるようにする exFixed という jQuery プラグインを公開してるのですが、これについて以下のような質問を受けており、未回答の状態になってました。
fixさせる要素(私の場合はヘッダー)の高さを指定せず、テキスト量が増えたりや文字サイズが大きくなってヘッダーの高さが広がった場合、次に続く要素(私の場合はコンテンツ)の開始位置も合わせて下がるということは可能でしょうか?
exResize でヘッダーのリサイズを検出し、ヘッダー高さ分の padding を body 要素に当てることで対応できるかと思います。
var target = $('div.header'); target //ヘッダーを固定位置に表示 .exFixed({ width : '100%', height : 'auto', //auto 指定は Ver.1.3.0 以降 top : 0, left : 0 }) //リサイズ時と画面描画時にヘッダー高さ分の padding を body に割り当てる .exResize((function(){ $('body').css({'padding-top':target.outerHeight()}); return arguments.callee; })());
ちなみにここでは、サイズ指定に auto が指定できる最新版(1.3.0 RC1)の exFixed を使用してますので、利用に際しては exResize の配布 zip ファイルに同梱された exFixed をお使いください。
カラム高さの整列処理をサイズ縮小時にも対応させる
よくあるカラムの高さを揃えるプラグインですが、大抵の実装は min-height を指定して高さを揃えてるため、カラム要素が縮んだ場合は高さが変わりませんが、ここでは縮小時の高さ調整にも対応するようにしてみます。
//プラグイン定義 (function($){ $.fn.exEqualHeight = function(){ //リサイズイベントの割り当て var api = this.exResize({ api : true, //api オブジェクトの返却を指定 contentsWatch : true, //内包要素の外周サイズを監視 callback : function(){ adjust( api ); } }); //サイズ調整処理 var adjust = function(api){ var maxHeight = 0; //各要素毎の API オブジェクトを参照 api.each(function(){ //最大の高さを取得 height = this.getSize().height; maxHeight = height > maxHeight ? height : maxHeight; }); //全要素を最大の高さにする api.getTargets().height(maxHeight); }; adjust( api ); }; })(jQuery); //プラグイン適用 jQuery(function($){ $('div.todo-a,div.todo-b').exEqualHeight(); });
簡易的なプラグンとして書いてみました。contentsWatch パラメータの指定により、リサイズの検出対象を内包要素の外周にする事で、height() メソッドによる自要素サイズの確定後も、継続したリサイズ検出をできるようにしています。