チップスとトリック

Tips and Tricks Tips and Tricks *
*前のトピック: カラーテーブル
*次のトピック: DHTMLチュートリアル

チップスとトリック

他のプログラミングと同様に、バグ無しで、期待通りの効果を出すスクリプトを書くのはやや大変である。ここでは、無駄な時間を使わず少しでもスムーズにプログラムできるように、チップスやヒントを説明する。

arrowr.gifInternet Explorerのバージョン番号を確かめる

arrowr.gifボタンクリックをキャンセルする

arrowr.gifドキュメントのキャッシュを抑制する

arrowr.gifオブジェクトを使う

arrowr.gifカスタムコントロールの代わりにDynamic HTMLを使う

Internet Explorerのバージョン番号を確かめる

スクリプトで必ずブラウザのバージョンを確かめるべきである。そうすれば、そのブラウザがInternet Explorer version 4の新機能をサポートしていない場合にスマートにグレードを落とすことができる。そのブラウザがInternet Explorerであるか、バージョン番号が何かを知る簡単な方法は、次のようなJScriptの関数を使うことである。

  function msieversion()
  // Microsoft Internet Explorerのメジャーバージョン番号を返す。他のブラウザの場合には0を返す。
  // この関数は"MSIE "という文字列を探し、バージョン番号を解析する。
  // 空白に続いて小数点までがメジャーバージョンである。それ以下はマイナーバージョンで無視される。
  {
  var ua = window.navigator.userAgent
  var msie = ua.indexOf ( "MSIE " )
  if ( msie > 0 )        // Microsoft Internet Explorerの場合、バージョン番号を返す。
  return parseInt ( ua.substring ( msie+5, ua.indexOf ( ".", msie ) ) )
  else
  return 0    // その他のブラウザ
  }

この関数は、主要なブラウザでは実行可能である。Microsoft Internet Explorerならそのメジャーバージョン番号を返し、その他のブラウザなら0を返す。この関数を使えば、Internet Explorerの最新バージョンのスクリプトと互換性があるかどうか確認できる。

スクリプトによって、ブラウザのバージョンが、必要とするバージョン以上であることを確認すべきである。userAgentが"MSIE 3"と同じかどうかチェックする既存のスクリプトがあるなら、バージョンを正しく識別できるように変更すべきである。それによって、以前のバージョンの全ての機能をサポートしているInternet Explorer 4.0を認識できるようになる。

次の例は、ブラウザのバージョンを正しく認識する方法を示している。

  if ( msieversion() >= 4 )
  document.alert( "This is IE4 or later - safe to use all IE4 features" )
  else if ( msieversion() >= 3 )
  document.alert( "This is IE3 - safe to use ActiveX" )
  else
  document.alert( "This is not IE" )

ボタンクリックをキャンセルする

次のHTML例は、デフォルトアクション処理とそのキャンセルに関するイベントを扱う際にありがちなスクリプトの間違いを示す。

  <HTML>
  <HEAD><TITLE>Canceling the Default Action</TITLE>
  <SCRIPT LANGUAGE="JScript">
  function askConfirm() {
  return window.confirm ("Choose OK to follow hyperlink, Cancel to not.")
  }
  </SCRIPT>


  <BODY onload="b3.onclick=askConfirm">
  <!-- Try links with different hookups - should be canceled by "Cancel" to confirm dialog. -->


  <BR><A NAME=b1 HREF="https://www.microsoft.com" onclick="askConfirm()">1 Without return (won't work)</A>


  <BR><A NAME=b2 HREF="https://www.microsoft.com" onclick="return askConfirm()">2 With return (works)</A>


  <BR><A NAME=b3 HREF="https://www.microsoft.com">3 Function pointer (works)</A>


  </BODY>
  </HTML>

この例の最初のAエレメントは正しく動作しない。JScriptでのonclickにおいてreturnが指定されていないと、ブラウザはその関数を解釈して、その結果の値を返すことができない(これは文ではあっても、何も割り当てられていない)。そしてデフォルトアクションが起きないことになる。

その他のAエレメントは、イベントに戻り値が正しくバインドされ、その結果falseが返されればデフォルトアクションがキャンセルできるようになっている

ドキュメントのキャッシュを抑制する

次のMETAタグをドキュメントに追加することで、ドキュメントをキャッシングさせないようにすることができる。

  <META HTTP-EQUIV="Expires" CONTENT="0">

ドキュメントをキャッシュさせなければ、ブラウザでのキャッシュ オプションがどのように設定されていようと、常に最新のドキュメントをサイトから読み出すことになる。これは、コンテンツが頻繁に変更されるような場合には有効である。

オブジェクトを使う

オブジェクトとは、ActiveXコントロールや同様の他のコンポーネントのことであり、HTMLドキュメントに対してカスタム機能やサービスを提供するOBJECTエレメントを使うことによって、ドキュメントにコントロールを追加できる。そして、スクリプトからそのプロパティやメソッドを用いてコントロールの機能やサービスを利用することができるようになる。

オブジェクトを使う場合、Dynamic HTMLでは、以下のプロパティの追加で各オブジェクトが拡張されている点に注意すること。

align BaseHref
classid code
codeBase codeType
data form
height name
object recordset
type width

コントロールが同じ名前のプロパティを持っている場合、そのプロパティにアクセスするには、その名前のプレフィックスとしてobjectプロパティを付けなければならない。例えば、以下のようにActiveXコントロールがドキュメントに追加されたとする。

  <OBJECT ID="MyControl" HEIGHT=100 WIDTH=200 CLASSID="clsid: ... ">
  </PARAM NAME="width" VALUE="400">
  </OBJECT>

この例では、2つのwidthが指定されている。1つはOBJECTエレメントの拡張プロパティであり、もう1つはPARAMエレメントを使って設定されたコントロールに属するプロパティである。スクリプトからこれらにアクセスするためには、次のようにする。

  alert(MyControl.width);   // これはDynamic HTMLプロパティ; "200"
  alert(MyControl.object.width);  // これはオブジェクトのプロパティ; "400"

カスタムコントロールの代わりにDynamic HTMLを使う

Dynamic HTMLでは、カスタムコントロールを使わずにアニメーション効果を作成するのに必要なすべてを提供している。例えば、次のようなスクリプトを考えてみよう。これはパンコントロールの代わりになる。

  var tickDuration;
  tickDuration = 50;

  var activeObjectCount;
  var activeObjects;
  var itemDeactivated;

  var tickGeneration;

  activeObjects = new Array();
  activeObjectCount = 0;
  timerRefcount = 0;
  itemDeactivated = false;

  tickGeneration = 0;

  function initializePath(e) {
  e.waypointX = new Array();
  e.waypointY = new Array();
  e.duration = new Array();

  }

  function addWaypoint(e, number, x, y, duration) {
  e.waypointX[number] = x;
  e.waypointY[number] = y;
  e.duration[number] = duration;
  }

  function compact() {
    var i, n, c;

    n = new Array();
    c = 0;
    itemDeactivated = false;
    for (i=0; i<activeObjectCount; i++)  {
      if (activeObjects[i].active == true) {
          n[c] = activeObjects[i];
          c++;
      }
    }

    activeObjects = n;
    activeObjectCount = c;
  }

  function tick(generation) {

    if (generation < tickGeneration) {
      // alert("Error "+generation);
      return;
    }

    //alert("tick: "+generation);

    if (itemDeactivated)
      compact();

    if (activeObjectCount == 0) {
      return;
    }
    else {
      for (i=0; i<activeObjectCount; i++) {
        moveElement(activeObjects[i]);
      }

      window.setTimeout("tick("+generation+");", tickDuration);
    }
  }

  function start(e) {
    if (itemDeactivated)
      compact();

    activeObjects[activeObjectCount] = e;
    activeObjectCount++;

    if (activeObjectCount == 1) {
      tickGeneration++;
      tick(tickGeneration);
    }
  }

  function runWaypoint(e, startPoint, endPoint) {

    var startX, startY, endX, endY, duration;

    if (e.waypointX == null)
      return;

    startX = e.waypointX[startPoint];
    startY = e.waypointY[startPoint];
    endX = e.waypointX[endPoint];
    endY = e.waypointY[endPoint];

    duration = e.duration[endPoint];
    e.ticks = duration / tickDuration;

    e.endPoint = endPoint;
    e.active = true;
    e.currTick = 0;

    e.dx = (endX - startX) / e.ticks;
    e.dy = (endY - startY) / e.ticks;

    e.style.posLeft = startX;
    e.style.posTop = startY;

    start(e);
  }

  function moveElement(e) {
    e.style.posLeft += e.dx;
    e.style.posTop += e.dy;

    e.currTick++;

    if (e.currTick > e.ticks) {
      e.active = false;
      itemDeactivated = true;
      if (e.onpathcomplete != null) {
        window.pathElement = e;
        e.onpathcomplete()
      }
    }
  }

このスクリプトをドキュメント中で使うには、次のようにすること。

  1. SCRIPTエレメントのsrc属性を使ってスクリプトをロードする。
  2. initializePath関数によってパスを初期化する。
  3. addWaypoint関数によってwaypointを設定する。
  4. runWaypoint関数によってpathcompleteハンドラを設定する。

次のサンプルドキュメントで、どのように動作するかがわかる。

  <html>
  <body>
  <div id=Item1 style="position: absolute; left: 0; top: 0;">Item1</div>
  <div id=Item2 style="position: absolute; left: 0; top: 0;">Item2</div>
  <div id=Item3 style="position: absolute; left: 0; top: 0;">Item3</div>
  <div id=Item4 style="position: absolute; left: 0; top: 0;">Item4</div>
  <div id=Item5 style="position: absolute; left: 0; top: 0;">Item5</div>
  <div id=Item6 style="position: absolute; left: 0; top: 0;">Item6</div>

  <input type=button value="Start" onclick="runWaypoint(Item1, 0, 1); runWaypoint(Item2, 0, 1);">
  <div id=Debug>Generation</div>

  <script src="htmlpath.js">
  </script>

  <script>

  // このメカニズムを使って、移動させる全てのオブジェクトに対してinitializePathをコールする必要がある。
  initializePath(Item1);
  initializePath(Item2);
  initializePath(Item3);
  initializePath(Item4);
  initializePath(Item5);
  initializePath(Item6);

  // 0番目のwaypointはwaypoint #1の最初の位置である。
  // addWaypointの構文は(item, waypoint, endx, endy, duration)。durationはミリ秒。
  addWaypoint(Item1, 0, 0, 0, 0);
  addWaypoint(Item1, 1, 200, 200, 2000);

  addWaypoint(Item2, 0, 100, 100, 0);
  addWaypoint(Item2, 1, 400, 100, 4000);

  addWaypoint(Item3, 0, 400, 400, 0);
  addWaypoint(Item3, 1, 200, 100, 1000);

  addWaypoint(Item4, 0, 0, 0, 0);
  addWaypoint(Item4, 1, 200, 200, 2000);

  addWaypoint(Item5, 0, 100, 100, 0);
  addWaypoint(Item5, 1, 400, 100, 4000);

  addWaypoint(Item6, 0, 400, 400, 0);
  addWaypoint(Item6, 1, 200, 100, 1000);

  function endfunction() {
    // runWaypointの構文は(Item, 開始ポイント, 終了ポイント)。
    runWaypoint(Item3, 0, 1);
    runWaypoint(Item4, 0, 1);
    runWaypoint(Item5, 0, 1);
    runWaypoint(Item6, 0, 1);

  }

  function endfunction2() {
    runWaypoint(Item1, 0, 1);
  }

  Item1.onpathcomplete = endfunction;
  Item6.onpathcomplete = endfunction2;

  </script>
  </body>
  </html>

Up トップに戻る
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.