07 | 2017/08 |  09

  1. 無料サーバー

User forum-FC2BLOG-Info-Edit Template-Post-Edit-Upload-LogOut

CSSやJavascript自習の苦闘史を綴っていきたい。恐縮ですがJavascriptを有効にしてご覧ください。
2005年12月から社会問題も掲載!

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

 

jQuery の各種メソッドを活用して、マウスカーソルの現在位置や要素の位置とサイズなどを取得する

はじめに───ここで行ったこと

このエントリイでは、jQuery の各種メソッドを活用して、まず、マウスカーソルの現在位置の頁座標を取得/表示し、また要素の頁座標と offsetParent 座標値並びに大きさを取得/表示させます。

次に、要素をアニメーションさせた直後に、当該要素の絶対/相対座標値や要素の各サイズ値を取得/表示させます。その際には、値が変わった箇所を一目で分かるように工夫しました。

このアニメーションは要素が往復運動するもので、1の往復運動毎にその動く方向・距離・内容幅・内容高さを乱数を発生させて変動させています。何度か繰り返しアニメーションさせてみると乱数の効果を良く確認出来るでしょう。box2 と box3 に別々の乱数を割り振ったので、「往路」の方向も移動距離も幅と高さの変化率もお互いに異なりますが、復路は必ず最初の位置とサイズに戻るようにプログラミングしました。

また、往路復路の別を分かりやすくするために、往路が終わると要素が半透明になるようにしました。この状態は復路が終わると当初の不透明に戻ります。

testArea...pos:rel
tester1
pos:stat
box1
pos:rel
tester2
pos:rel
box2
pos:abs
tester3
pos:rel
box3
pos:abs
tester4
pos:abs
tester's position
itemAreatester1tester2tester3tester4
Left
Top
posLeft
posTop
width
innerW
outerW
marginW
height
innerH
outerH
marginH
box's position
box1box2box3

※ ピンクの背景色セルは、その値が直前値から変化したことを示す。

▲ToTop

1. マウスカーソルの現在座標値をリアルタイムで取得し表示する

マウスカーソルの現在座標値は、jQuery のイベントに係るメソッドを利用すれば、極めて簡単に取得できます。ブラウザ毎の計測方法の差異は jquery.js が処理してくれるので、後述するように、座標値取得のための javascript コードは極めて簡潔になります。

次に、取得したマウスカーソル座標値の表示については、上の背景色ロイヤルブルーのボックス内にマウスカーソルが入った時にのみ、マウスカーソルの右下にマウスカーソルの頁座標値を表示するようにしました。更に、当該ボックス内でマウスカーソルが移動した場合には、マウスカーソルに追随して座標表示ボックスを移動させ、かつ、刻々と変化する座標値を瞬時に表示するようにしました。

つまり、マウスカーソルの移動に合わせてリアルタイムでその座標値を取得し、座標値の表示場所はマウスカーソルに追随して移動するようにしました。

2. 要素の頁座標値とoffsetParentからの座標値、並びに大きさを取得し表示する

要素の位置と大きさを取得するために利用する jQuery メソッドは次の 10 個です。

offset、position、width、height、
innerWidth/Height、outerWidth/Height、outerWidth(true)/Height(true)

これらの jQuery インスタンスメソッドを使用すれば、極めて容易に要素の位置とサイズが取得出来ます。

jQuery(要素).offset インスタンスメソッドは、対象要素が含まれる表示領域の左辺または上辺から、対象要素のボーダー辺までの横又は縦方向の距離(頁内絶対座標とでも呼ぶべきか?)を計測し、jQuery(要素).position は、対象要素の offsetParent 要素のパディング辺からの、対象要素のマージン辺の横又は縦方向の距離を計測するメソッドです。このことの詳細は、「 jquery.js (1.4) による要素位置の測定と適正な配置 (2) コード解読(1) 」 に詳述しました。

また、width/height、innerWidth/Height、outerWidth/Height及びouterWidth(true)/Height(true)は、順に対峙する内容辺間距離、パッディング辺間距離、ボーダー辺間距離、マージン辺間距離を計測するメソッドです。詳細は拙エントリイ:「 jquery.js (1.4) による要素位置の測定と適正な配置 (5) コード解読 (4) 」を参照してください。画像付きで説明しています。

取得した値は、このエントリイ上部に配置した tester's position 表と box's position 表に表示させました。ここに、Left と Top は頁座標値で offset メソッドを使って、また posLeft と posTop はoffsetParent からの座標値で、position メソッドを使って、それぞれ取得しています。

また、offsettParent の定義から、各 tester ボックスの offsettParent は testAreaとなり、各 box の offsetParent は各 tester ボックスとなります。( 因みに testArea の offsetParent は div#container であり、更に div#container の offsetParent は body となります。body 以外の offsetParent とする要素は、全て CSS スタイル設定で position:relative を指定し、明示的にoffsetParent となるようにしました。)

▲ToTop

3. 要素を移動させるアニメーションと移動後の座標値の取得/表示について

ここで作成したアニメーションは 2 つの div 要素を、ほぼ同時に上 or 下かつ左 or 右に移動させながら、同時に幅と高さを変化させるものです。目的はアニメーションそのものよりも、移動前後の座標値の取得/表示を主眼としましたが、アニメーションそのものにも、少しは興味を引くであろう様々な工夫を凝らしました。(アニメーションの起動はエントリイ上部に配置した animate ボタンをクリックして行います。)

工夫は、単純な移動やサイズ変更の繰り返しでは詰まらないので、乱数 Math.random() メソッドを使って、移動の度に方向・距離・内容サイズが変わるようにしました。easing 関数も乱数によって 11 種類からその都度任意に選択されるようにセットしたので、クリックする度に異なる方向、異なる距離、,異なるサイズ、異なる easing を使ってアニメが展開されます。

また、ここで作成した移動と大きさ変更アニメーションは、往復運動で 1 サイクルになるようにしたので、往路の移動とサイズ変更が終わると要素が半透明になるようにして、往路であることが分かるようにしました。当然ですが復路が終わると位置と大きさは元に戻り、不透明度も 100 %に戻るようにしました。

4. このエントリイのためのスタイルシート

■スタイルシート
#testArea {
  position:relative;background:royalblue;width:520px;padding:1em;/*height:360px;*/
}
.tester {margin:0.5em;width:100px;height:150px;}
#tester1 {border:solid white 2px;} /*position:static*/
#tester2 {position:relative;background:darkred;border:solid yellow 2px;}
#tester3 {position:relative;background:teal;border:solid white 2px;}
#tester4 {position:absolute;top:10px;left:370px;border:solid lime 2px;}
.box {
  position:absolute;top:50px;left:20px;background:indigo;border:solid lime 2px;
  width:66px;height:80px;
}
#box1 {position:relative;}
#result {margin:1em 0;border:1px lightgray dotted;padding:2px;background:dimgray;}
table#table1 input,table#table2 input {width:65px;text-align:right;background:white}
table#table1 caption,table#table2 caption {color:lime}
table#table1 th,table#table2 th {line-height:0.5em;text-align:center}
table#table1 tr,table#table2 tr {line-height:1em;}
button#animBtn {display:block;position:absolute;top:180px;left:400px;z-index:10;}
div#testArea div#log {position:relative;z-index:9;padding-top:4em;line-height:1.1em;}

▲ToTop

5. jQuery の各種メソッドを活用したこのエントリイのための Javascript コードの解説

■javascript code
  // マウスカーソルの座標値を表示するためのdiv要素を作成する。
  $("<div id='testBalloon' />").css({
      position:"absolute",padding:"0.5em",border:"1px solid green",
      display:"none",background:"navy",zIndex:11
  }).appendTo("body");
  var o ={ // 各種 jQuery インスタンスへのショートカットなどを登録するオブジェクト
    $cont: $("#container"),
    $tArea: $("#testArea"),
    $t1: $("#tester1"),  $t2: $("#tester2"),
    $t3: $("#tester3"),  $t4: $("#tester4"),
    $tbl1: $("#table1"), $tbl2: $("#table2"),
    $input: $("input","#result"),  $log: $("#log"),
    $tBalloon: $("#testBalloon"), rnd:{}, // 乱数を格納するオブジェクト
    easing:["swing","easeInOutQuad","easeInOutCubic","easeInOutQuart","easeInOutQuint",
    "easeInOutSine","easeInOutExpo","easeInOutCirc","easeInOutElastic","easeInOutBack",
    "easeInOutBounce"], //easing 関数を登録
    cnt: 0, //カウンター
    flag: true //奇数偶数区別用
  };
  // 各 box へのショートカットを登録する
  o.$b1= $(o.$t1).children(":eq(1)");
  o.$b2= $(o.$t2).children(":eq(1)").css("zIndex","2");
  o.$b3= $(o.$t3).children(":eq(1)").css("zIndex","3");
  // document 内でマウスカーソルが動いた時に、その座標値を o オブジェクトのプロパティに登録する。
  // たったこれだけのコードで目的を達成することが出来る。
  $(document).bind('mousemove',function(e){ 
    o.x = e.pageX;
    o.y = e.pageY;
  });
  // エリア内にマウスカーソルがある時と外れた時の、
  // マウスカーソル座標値を表示するボックスの表示/非表示を制御する。
  o.$tArea.hover(
    function(){o.$tBalloon.fadeIn()},
    function(){o.$tBalloon.fadeOut()}
  ).mousemove(function(){
    // エリア内でマウスカーソルが動いた時に座標値を表示する。
    // 座標値の表示ボックスは、マウスカーソルの右下に 16 pxずれた箇所に表示する。
    o.$tBalloon.html("<div>top: "+ o.y+ "px<br />left: "+o.x+"px</div>")
      .css({top:parseInt(o.y)+16+"px",left:parseInt(o.x)+16+"px"})
  });

  // 要素の位置と大きさを計測する関数を再呼び出し出来るように定義する。
  var doCalc = function(){
    $.each([o.$cont,o.$tArea,o.$t1,o.$t2,o.$t3,o.$t4,o.$b1,o.$b2,o.$b3],function(){
      this.oSet = $(this).offset(); // jQuery.offset メソッド
      this.pos = $(this).position(); // jQuery.position メソッド
      this.left = this.oSet.left; // jQuery.offset().left 値取得
      this.top = this.oSet.top; // jQuery.offset().top 値取得
      this.posLeft = this.pos.left; // jQuery.position().left 値取得
      this.posTop = this.pos.top; // jQuery.position().top 値取得
      this.width = $(this).width(); // 内容辺間の幅取得
      this.innerW = $(this).innerWidth(); // padding 辺間の幅取得
      this.outerW = $(this).outerWidth(); // border 辺間の幅取得
      this.marginW = $(this).outerWidth(true); // margin 辺間の幅取得
      this.height = $(this).height(); // 内容辺間の高さ取得
      this.innerH = $(this).innerHeight(); // padding 辺間の高さ取得
      this.outerH = $(this).outerHeight(); // border 辺間の高さ取得
      this.marginH = $(this).outerHeight(true); // margin 辺間の高さ取得
    });
  }
  doCalc(); //関数実行
  // アニメーションで使用するために、4 つのプロパティの初期値を
  // アニメ対象オブジェクトの2 つのプロパティの初期値を org プロパティに記憶させる
  $.each([o.$b2,o.$b3],function(i,n){
    n.org={};
    $.each(["posLeft","posTop","width","height"],function(){
      n.org[this] = n[this];
    });
  });

  // 位置やサイズ値をエントリイ内の表内に挿入する関数
  var insertValue = function(ary,obj){ // ary は計測対象要素、obj は挿入対象 table。
    $.each(ary,function(i,n){
      $.each(["left","top","posLeft","posTop","width","innerW","outerW","marginW","height","innerH","outerH","marginH"],
        function(j){
          o.tmp=$(obj).find("input:eq("+(i+j*ary.length)+")");
          o.tmp.before=o.tmp.attr("value") || 0; // 直前の値
          // 各要素の各属性値を取得する。
          o.tmp.attr("value",parseInt(n[this],10)); // n は各要素、this は属性
          o.tmp.after=o.tmp.attr("value");
          // 前後の属性値が異なれば背景色を変化させる。
          o.tmp.before !== o.tmp.after ? o.tmp.css("background","pink")
          : o.tmp.css("background","white");
      });
    });
  };
  insertValue([o.$tArea,o.$t1,o.$t2,o.$t3,o.$t4],o.$tbl1);
  insertValue([o.$b1,o.$b2,o.$b3],o.$tbl2);
  o.$input.css("background","white"); // (初期値として)背景色をホワイトに設定する。
  // 移動アニメーション関数の定義
  var trans = function(){
    o.$input.css("background","white"); // 背景色の初期化
    // box2 の移動アニメーション。trans 関数は call メソッドを使ってo.rndオブジェクト
    // から呼び出すため、this は o.rnd オブジェクトを参照することになる。
    // this の各プロパティは $("#animBtn").click メソッドを参照のこと。
    o.$b2.animate({
      // アニメ終了値は全て相対移動量で設定する
      left: this[1]+"="+this[5][0]+"px",
      top: this[2]+"="+parseInt(this[5][0]/2)+"px",
      width: this[1]+"="+ Math.round(o.$b2.org.width*this[6][0])+"px",
      height: this[2]+"="+ Math.round(o.$b2.org.height*this[6][1])+"px",
      opacity: o.flag ? 0.5 : 1
      // 奇数回目には半透明に、偶数回目には不透明に。
      opacity: o.flag ? 0.5 : 1
    },1000,o.easing[parseInt(o.rnd[0][0]*11)]);
    o.$b3.animate({
      left: this[3]+"="+ this[5][1] +"px",
      top: this[4]+"="+ parseInt(this[5][1]/2) +"px",
      width: this[3]+"="+ Math.round(o.$b3.org.width*this[6][1]) +"px",
      height: this[4]+"="+ Math.round(o.$b3.org.height*this[6][0]) +"px",
      opacity: o.flag ? 0.5 : 1
    },1000,o.easing[parseInt(o.rnd[0][1]*11)],function(){ //アニメーションが終わってから、移動後の座標値を挿入する。
      doCalc(); insertValue([o.$b1,o.$b2,o.$b3],o.$tbl2);
    });
  }
  // アニメの動作ログを作る。
  var insertLog = function(){
    var ary = []; // 偶数回目の移動方向を反転表示とするため
    $.each([this[1],this[2],this[3],this[4]],function(i,n){
      ary[i] = o.flag ? n : (n==="+" ? "-" : "+");
    });
    o.$log.html(
      "<div>box2 の移動方向と距離のための乱数:"+ this[0][0] + "</div>"+
      "<div>box3 の移動方向と距離のための乱数:"+ this[0][1] + "</div>"+
      "<div>box2 の横移動距離:"+ary[0] +"=" + this[5][0]+"px, "+
      "box2 の縦移動距離:"+ary[1] +"=" + parseInt(this[5][0]/2)+"px</div>"+
      "<div>box3 の横移動距離:"+ary[2] +"=" + this[5][1]+"px, "+
      "box3 の縦移動距離:"+ary[3] +"=" + parseInt(this[5][1]/2)+"px</div>"+
      "<div>サイズ増減のための 2 つの乱数:<br />  "+this[6][0]+","+this[6][1]+"</div>"+
      "<div>box2 の横方向サイズ増減倍率、又は box3 の縦方向サイズ増減倍率:<br />  "+this[6][0] +"</div>"+
      "<div>box3 の横方向サイズ増減倍率、又は box2 の方向サイズ増減倍率:<br />  "+this[6][1] +"</div>"+
      "<div>box2 の移動に適用されたeasing:"+o.easing[parseInt(o.rnd[0][0]*11)]+"</div>"+
      "<div>box3 の移動に適用されたeasing:"+o.easing[parseInt(o.rnd[0][1]*11)] +"</div>"
    );
  };
  // animate ボタンがクリックされたら実行する。
  $("#animBtn").click(function(){
    var i=1;
    o.flag = ++o.cnt % 2; // 奇数回目(true) か、偶数回目(false )か?
    if (o.flag){ // 奇数回目ならば
      // 移動方向、移動距離、サイズ変更等に使用する乱数を発生させる。
      // o.rnd は乱数を使った各種プロパティを格納するオブジェクトである。
      o.rnd[0]=[Math.random(),Math.random()];
      // 乱数値の小数点第 1 ~ 4 位迄の各桁の数値が偶数ならば+を、
      // 奇数ならば-を o.rnd[i] に順に代入する。これにより 2 つのボックス
      // それぞれの横及び縦方向の移動方向をランダムに設定する。
      for (;i<5;i++)
          o.rnd[i] = parseInt(o.rnd[0][0] * Math.pow(10,i)) % 2 === 0 ? "+" : "-";
      // box2 と box3 の移動距離を設定 (0 ~ 199)
      o.rnd[5] =[parseInt(o.rnd[0][0]*200),parseInt(o.rnd[0][1]*200)];
      // box2 と box3 のサイズ変動倍率を設定 (-0.5 ~ +0.49999)
      o.rnd[6] =[o.rnd[0][0]-0.5,o.rnd[0][1]-0.5];
    } else {
        // 偶数回目では正負記号を反転させる
        for (; i<5; i++) o.rnd[i] = o.rnd[i]==="+" ? "-" : "+";
    }
    trans.call(o.rnd); // アニメーション開始
    insertLog.call(o.rnd); // アニメーションに係るログを表示する。
    $(this).blur(); // ボタンからフォーカスを外す。
  });

▲ToTop

6. javascript コード作成上留意したこと

HTML、CSS、Javascriptの役割分担

一部に style 属性を設けましたが、出来るだけ文書構造(HTML)、表示(CSS)及び動作(Javascript)は区別しました。

出来るだけ変数の数を減らしました

無名関数で括る必要はなかったのでトップレベルの変数はグローバルになります。そこで可読性をたかめるためにも、トップレベルの変数は 1 つにまとめました。具体的には基礎的な変数を var o オブジェクトプロパティにまとめて、関数以外のトップレベルの変数は var o だけとしました。

jQuery インスタンスの表記上の扱い

jQuery インスタンスを複数回使用する場合には、そのショートカットを作成し、かつ jQuery インスタンスと一目で分かるような独自の名称にしました。具体的には、変数名の 1 文字目に $ 記号を付けました。

ランダムなアニメーションとするために、乱数をさまざまに加工しました

移動する方向、移動距離、サイズの変動率、アニメに適用する easing 関数の選択などを、ランダムに設定しましたが、その各々に乱数を発生させるのではなく、発生させた 1 つの乱数を加工して使い回しました。

アニメ終了後に実行させる行為の扱い

jQuery(要素).animate メソッドでは当該アニメーション終了後に行わせる行為は、所定の方法で記述しなければなりません。或る行為を単にこのメソッド以降の行に既述すると、アニメーション実行中もコード進行は進みますから、アニメーション終了を待たずに当該行為が実行されてしまうからです。

久々に animate メソッドを使用したため、そのことに気がつくのに時間を要してしまい、アニメーション終了後の処置を相応しいタイミングでブラウザに反映させることがなかなか出来ず、徒労を重ねてしまいました。

ボタンクリックによる往復アニメの工夫

アニメーションを起動するボタンは簡潔に 1 つだけとしましたが、ここで作ったアニメーションには往路と復路があり、2 回のアニメーションが 1 セットになっています。そこで最初の段階では、click メソッドではなく toggle メソッドで往復アニメーションを実現させていました。

そして移動方向/距離もサイズ変更も、before と afterで、符号を変えて往復アニメを実現していました。

しかし、効率的なコード記述にすべきだと考え、click 数に応じた flag を用意して click メソッドを採用することにしました。

また、アニメの終点値には、"+=" 等の相対変動値を採用しましたが、これには大きな意味があります。絶対変動値指定を採用すると、コードは長大になるばかりで美しくないのです。相対変動値の採用は往復アニメーションにおける重要なポイントでしょう。

▲ToTop

 

■ コメントの投稿 ■

管理者にだけ表示を許可する

●トラックバック●

■トラックバックURLはこちら■
http://hkom.blog1.fc2.com/tb.php/780-fa8dc4be

●参照元一覧●

<provided Fc2>
<provided i2i>

▲ToTop

 90%近いシェアを握っているインターネットエクスプローラの描画エンジンを利用したタブbrowser。沢山のタブbrowserがあるが、多機能、カスタマイズフリー、スクリプト利用等で一日の長がある。Gekkoエンジンへの対応も行われ、IEからの自立独立の方向に向かっている。2005年7月にはIE7が登場する見通しの中で、今後の発展が望まれる。

 多様なCSS作成支援機能を備えた、タグ入力式 HTML&CSS作成支援エディタ。スキンデザインもすっきりしている。テキストエディター上で作成するよりも確実で安全にタグ打ちが出来る。
文字コードを選べないのが欠点。

 StyleNote同様のタグ入力式 HTML&CSS 作成支援エディタ。長年使用してきたが現在StyleNoteに乗り換えつつある。

 クリップボード履歴情報を活用する為のソフト。画像まで履歴を取ってくれるのが嬉しい。このソフトを使わない日は絶対ない程に重宝し、愛用している。

 起動中のウィンドウの「コピーできない」説明文などの文字列を取得し、コピー可能な文字データにするツール。何かと便利。

 ストリーミングデータを保存することが出来るソフト。動画利用には不可欠なソフトだ。

 無料ながらレイヤー機能を有し、スクリプトによる拡張も可能な、sleipnir作者が提供している優れもの画像編集ソフト。

 画面キャプチャソフトと言えばこれに勝るものなし、ではないだろうか? 様々な取得方法を有しており、ブログ作成にもHomepage作成に不可欠だ。Jtrimと並んでWoodyBellsの作品。

 複数ファイルの同時編集は出来ないが、透過pngも作れる画像編集ソフト。
(以下当該サイトから抜粋)初心者にも簡単に操作が出来るフォトレタッチソフトです。多くの加工機能で画像に様々な効果を与えることができます。非常に軽快に動作するため、ストレスなく操作できます。

 Animation Gifファイルを作れる無料ソフト。

 キャプチャソフト。画面内にサイト全体が表示しきれない場合でも、これを使えば全体をキャプチャすることが出来る。

 画像処理。画像のフォーマット変換のみならず、色数やサイズ、圧縮率の変更まで一括処理できてしまう『BatchGOO!』は、大量の画像をまとめて処理したいときに大変便利なソフト。BMP, TIFF, JPEG, PCX, PNG の相互変換をはじめ、色数・サイズ・解像度の統一、JPEG圧縮率の調節など、ホームページ用の画像や携帯電話用の壁紙を揃えるのに抜群の相性を見せる。(Vectorの当該ソフト紹介頁より抜粋引用)

 名前から直ぐに想像が付くように画像のサイズを測るためのソフトだ。Homepage作成には欠かせない。2カラム、3カラムのレイアウトを行う場合に大変重宝する。

 ランチャーソフトは沢山あるが、中でもこれが一押しだ。2年以上使ってきたがその操作性には毎日満足している。これを使い始めてからデスクトップには一切のアイコンを表示することをやめてしまった。

 AdobeReader7によって、起動時間が長すぎるという長年のユーザーの不満はある程度解消した。そのためこの高速化ソフトは存在価値が低下してしまったかもしれない。AdobeReader6迄はこのソフトによる起動高速化で恩恵を受けてきた。

 IE専用が難点だが、様々なサイト内でIDやパスワードを入力するのに重宝するソフト。コンテキストメニューから簡単に起動できるのがGood! sleipnir等のIEの描画エンジンを利用しているブラウザでも使える。

 利用しているパソコンの諸元値を取得するには、このソフトがベストだ。インストール済みソフトの一覧が取得できるのも嬉しい。

 WMPは機能が豊富なだけ重い。RealPlayerも同様だ。そこでMedia Player Classicを使いたい。動作が軽快なだけではなく、対応しているファイル形式もすこぶる多く、これひとつで、wmvもrmも表示できてしまうのだから凄い! 数多あるMedia Playerの王様と言えるだろう。

 自宅でPCを起動しているときには必ず起動しているメディアプレーヤー。何かと過剰なWinampよりも、起動も速くスキンはシンプルだ。

 DivX, Xvid, Mov, Vob, Mpeg, Mpeg4, avi, wmv, dv, などの動画をDVD-Video形式に変換できるフリーソフト。クリックするとDVD関連ソフト紹介サイト=「DVDなToolたち」なるHomepageが開きます。

----------
201007090028
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。