japan.internet.com The Internet & IT Network


RSSニュース検索
カテゴリ
> トップページ
> Webビジネス
> Eコマース
> Webファイナンス
> Webマーケティング
> パブリック
> Webテクノロジー
> 携帯・ワイヤレス
> Linux Today
> Linux Tutorial
> J.I.C.ブログ
キャリア
> 転職ならen
> 派遣ならen
> アルバイトならen
> IT求人情報
ヘッドライン
> 今日のヘッドライン
> 週間ヘッドライン
Special Link
> フォトコミュニティ
> ストックフォト
> クリップアート
> イラスト
> フェリカ
> Web2.0
> 写真
イベント&セミナー
> イベントカレンダー
> 書評「IT の耳」
> 出張・接待検索
> ニュースガジェット 注目
無料ニュースメール
> 新規登録
> 変更・解除
> オプトインメールの登録・変更・解除
インフォメーション
> パートナーサイト
転職ならエン
就職ならen
求人ならen
履歴書ならen
アルバイトならエン
CRM/SFAならオラクル
> グループ会社
株式会社アエリア
(株)サンゼロミニッツ
株式会社エアネット
> お問い合わせ
> 広告掲載について
> リンクについて
> 著作権について
> その他お問い合わせ
> 利用規約
> 個人情報保護方針
> 会社概要地図
デベロッパー 2007年9月18日 17:50
デベロッパー・バックナンバー
JavaScriptでDOMレンジを扱う

著者: Nicholas C. Zakas  オリジナル版を読む プリンター用 記事を転送
2007年9月18日 17:50 付の記事
海外internet.com発の記事
このエントリーを含むはてなブックマーク この記事をクリップ! Buzzurlにブックマーク Yahoo!ブックマークに登録 newsing it!

はじめに

 DOMはWebページを処理するための非常に優れたAPIですが、一般的には標準のDOM機能ばかりが注目されています。多くの開発者は、DOMにただのcreateElement()appendChild()よりもっと便利な機能があることを知りません。DOMのRange(レンジ)は、Webページを動的に操作するための非常に強力なツールです。

 レンジを使用すると、ドキュメントのセクションをノード境界に関係なく選択できます(この選択は内部的に行われるため、ユーザーには見えません)。レンジは、通常のDOM操作では処理できないドキュメントの細部を変更したいときに役立ちます。

 DOM Level 2では、レンジを作成するcreateRange()というメソッドが定義されています。DOM対応のブラウザ(Internet ExplorerはDOM対応ではありません)では、このメソッドはdocumentオブジェクトに属しているので、次のようにして新しいレンジを作成できます。

var oRange = document.createRange();

 ノードと同様に、レンジはドキュメントに直接結び付いています。ドキュメントがDOMスタイルのレンジに対応しているかどうかを判断するには、hasFeature()メソッドを使用します。

var supportsDOMRanges = document.implementation.hasFeature("Range", "2.0");

 DOMのレンジを使用する場合には、まずこの点を確認し、次のようにコードをif文で囲んでおくことをお勧めします。

if (supportsDOMRange) {
   var oRange = document.createRange();
   //range code here
}

DOMレンジによる単純な選択

 DOMレンジを使ってドキュメントの一部を選択する最も単純な方法は、selectNode()またはselectNodeContents()を使用することです。これらのメソッドは、1つの引数(DOMノード)を受け取り、そのノードから取得した情報をレンジに割り当てます。selectNode()メソッドは指定されたノード全体(子を含む)を選択しますが、selectNodeContents()は指定されたノードのすべての子を選択します。たとえば、次のようなドキュメントがあるとします。

<p id="p1"><b>Hellob> Worldp>

 このドキュメントに対して、次のJavaScriptを実行したとしましょう。

var oRange1 = document.createRange();
var oRange2 = document.createRange();
var oP1 = document.getElementById("p1");
oRange1.selectNode(oP1);
oRange2.selectNodeContents(oP1);

 この例の2つのレンジには、ドキュメント内のそれぞれ異なるセクションが含まれます。oRange1には

要素とそのすべての子が含まれ、oRange2には要素とテキストノード「World」が含まれます(図1を参照)。

図1
図1

 レンジを作成すると、そのレンジには次のようなプロパティが割り当てられます。

  • startContainer
  • レンジの開始位置を含んでいるノード(選択内の最初のノードの親)。
  • startOffset
  • レンジの開始位置を含んでいるstartContainer内でのオフセット。startContainerがテキストノード、コメントノード、またはCDataノードである場合、このオフセットは、レンジを開始するまでにスキップする文字の数を表します。それ以外の場合は、レンジ内の最初の子ノードのインデックスを表します。
  • endContainer
  • レンジの終了位置を含んでいるノード(選択内の最後のノードの親)。
  • endOffset
  • レンジの終了位置を含んでいるendContainer内でのオフセット(startOffsetと同様のルールに従います)。
  • commonAncestorContainer
  • startContainerとendContainerの両方が含まれている最初のノード。

 これらのプロパティはすべて読み取り専用で、レンジについての補足情報を提供するために用意されています。

 selectNode()を使用した場合、startContainer、endContainer、commonAncestorContainerの各プロパティは、いずれも指定ノードの親ノードに等しくなります。また、startOffsetプロパティは指定ノードの親のchildNodesコレクションにおける指定ノードのインデックスに等しくなり、endOffsetプロパティは「startOffsetの値+1」に等しくなります(1つのノードだけが選択されるため)。

 selectNodeContents()を使用した場合、startContainer、endContainer、commonAncestorContainerの各プロパティは、いずれも指定ノードに等しくなります。また、startOffsetプロパティは0になり、endOffsetは子ノードの数(node.childNodes.length)に等しくなります。

 これらのプロパティの使用例を次に示します。

<html>
  <head>
    <title>DOM Range Exampletitle>
    <script type="text/javascript">
      function useRanges() {
          var oRange1 = document.createRange();
          var oRange2 = document.createRange();
          var oP1 = document.getElementById("p1");
          oRange1.selectNode(oP1);
          oRange2.selectNodeContents(oP1);

          document.getElementById("txtStartContainer1").value
              = oRange1.startContainer.tagName;
          document.getElementById("txtStartOffset1").value =
              oRange1.startOffset;
          document.getElementById("txtEndContainer1").value =
              oRange1.endContainer.tagName;
          document.getElementById("txtEndOffset1").value =
              oRange1.endOffset;
          document.getElementById("txtCommonAncestor1").value =
              oRange1.commonAncestorContainer.tagName;
          document.getElementById("txtStartContainer2").value =
              oRange2.startContainer.tagName;
          document.getElementById("txtStartOffset2").value =
              oRange2.startOffset;
          document.getElementById("txtEndContainer2").value =
              oRange2.endContainer.tagName;
          document.getElementById("txtEndOffset2").value =
              oRange2.endOffset;
          document.getElementById("txtCommonAncestor2").value =
              oRange2.commonAncestorContainer.tagName;
        }
    script>
  head>
  <body><p id="p1"><b>Hellob> Worldp>
    <input type="button" value="Use Ranges" onclick="useRanges()" />
    <table border="0">
    <tr>
        <td>
          <fieldset>
              <legend>oRange1legend>
              Start Container:
                  <input type="text" id="txtStartContainer1" /><br />
              Start Offset:
                  <input type="text" id="txtStartOffset1" /><br />
              End Container:
                  <input type="text" id="txtEndContainer1" /><br />
              End Offset:
                  <input type="text" id="txtEndOffset1" /><br />
              Common Ancestor:
                  <input type="text" id="txtCommonAncestor1" /><br />
          fieldset>
        td>
        <td>
          <fieldset>
              <legend>oRange2legend>
              Start Container:
                  <input type="text" id="txtStartContainer2" /><br />
              Start Offset:
                  <input type="text" id="txtStartOffset2" /><br />
              End Container:
                  <input type="text" id="txtEndContainer2" /><br />
              End Offset:
                  <input type="text" id="txtEndOffset2" /><br />
              Common Ancestor:
                  <input type="text" id="txtCommonAncestor2" /><br />
          fieldset>
        td>
    tr>
    table>
  body>
html>

 この例をFirefoxなどのDOM対応ブラウザで実行した結果を図2に示します。

図2
図2

 図を見てもわかるように、oRange1のstartContainer、endContainer、commonAncestorContainerの各プロパティはいずれも要素になります。これは、この

要素は完全に要素に含まれているからです。また、この

要素の最初の子は

要素なのでstartOffsetプロパティは0になり、このレンジは2つ目の子ノード(インデックス1)の前で終わるのでendOffsetプロパティは1になります。

 一方、selectNodeContents()メソッドで取得したoRange2の情報では、startContainer、endContainer、commonAncestorContainerの各プロパティはいずれも

要素になります。これは、このレンジでは

要素の子を選択しているからです。また、このレンジは

要素の最初の子ノードから始まっているのでstartOffsetプロパティは0になり、このレンジには

要素の2つの子ノード(とテキストノード「World」)が含まれているのでendOffsetプロパティは2になります。

 さらに、選択レンジをより細かく指定するために、次のようなメソッドが用意されています。これらのメソッドを使用すると、前述のプロパティには自動的に値が割り当てられます。

  • setStartBefore(refNode)
  • レンジの開始位置をrefNodeの前に設定します(したがって、refNodeは選択内の最初のノードになります)。startContainerプロパティはrefNodeの親に等しくなり、startOffsetプロパティはrefNodeの親のchildNodesコレクションにおけるrefNodeのインデックスに等しくなります。
  • setStartAfter(refNode)
  • レンジの開始位置をrefNodeの後ろに設定します(したがって、refNodeは選択内に含まれなくなり、その次の兄弟が選択内の最初のノードになります)。startContainerプロパティはrefNodeの親に等しくなり、startOffsetプロパティは「refNodeの親のchildNodesコレクションにおけるrefNodeのインデックス+1」に等しくなります。
  • setEndBefore(refNode)
  • レンジの終了位置をrefNodeの前に設定します(したがって、refNodeは選択内に含まれなくなり、その前の兄弟が選択内の最後のノードになります)。endContainerプロパティはrefNodeの親に等しくなり、endOffsetプロパティはrefNodeの親のchildNodesコレクションにおけるrefNodeのインデックスに等しくなります。
  • setEndAfter(refNode)
  • レンジの終了位置をrefNodeの後ろに設定します(したがって、refNodeは選択内の最後のノードになります)。endContainerプロパティはrefNodeの親に等しくなり、endOffsetプロパティは「refNodeの親のchildNodesコレクションにおけるrefNodeのインデックス+1」に等しくなります。

 これらのメソッドを使用すると、前述のプロパティに値が自動的に割り当てられます。複雑なレンジ選択を行いたい場合には、各プロパティに値を直接指定することもできます。

DOMレンジによる複雑な選択

 複雑なレンジを作成するには、レンジのsetStart()メソッドとsetEnd()メソッドを使用する必要があります。どちらのメソッドも、参照ノードとオフセットという2つの引数を取ります。setStart()では、参照ノードはstartContainerに割り当てられ、オフセットはstartOffsetに割り当てられます。setEnd()の場合、参照ノードはendContainerに割り当てられ、オフセットはendOffsetに割り当てられます。

 これらのメソッドを使用して、selectNode()およびselectNodeContents()と同等の機能を実現することができます。たとえば、前の例に出てきたuseRanges()関数を、setStart()setEnd()を使って次のように書き換えることができます。

function useRanges() {
    var oRange1 = document.createRange();
    var oRange2 = document.createRange();
    var oP1 = document.getElementById("p1");
    var iP1Index = -1;
    for (var i=0; i < oP1.parentNode.childNodes.length; i++) {
        if (oP1.parentNode.childNodes[i] == oP1) {
            iP1Index = i;
            break;
        }
    }

    oRange1.setStart(oP1.parentNode, iP1Index);
    oRange1.setEnd(oP1.parentNode, iP1Index + 1);
    oRange2.setStart(oP1, 0);
    oRange2.setEnd(oP1, oP1.childNodes.length);
    //textbox assignments here
}

 ノードを選択する(oRange1)には、まず目的のノード(oP1)について、その親ノードのchildNodesコレクションにおけるインデックスを特定する必要があります。ノードの内容を選択する(oRange2)には、特に計算は必要ありません。もっとも、既にご存知のとおり、ノードやノードの内容を選択するにはもっと簡単な方法が他にあります。この方法のポイントは、ノードの一部だけを選択できるということです。

 たとえば、

Hello World

というHTMLコードから、「Hello」の「llo」だけと「World」の「Wo」だけを選択したい場合を考えてみましょう。この方法を使えば、これを簡単に実現できます。

 まず、通常のDOMメソッドを使用して、「Hello」と「World」を含む2つのテキストノードの参照を取得します。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;

 テキストノード「Hello」は、実際には

の孫にあたるので(直接の親は)、oP1.firstChildによってを取得し、oP1.firstChild.firstChildによって目的のテキストノードを取得します。テキストノード「World」は

の2番目の(かつ最後の)子なので、oP1.lastChildによって取得できます。

 次に、レンジを作成して適切なオフセットを設定します。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);

 setStart()ではオフセットを2に設定します。これは、「Hello」中の1つ目の「l」は位置2にあたるからです(先頭の文字「H」は位置0です)。setEnd()ではオフセットを3に設定します。このオフセットには、選択しない最初の文字の位置を指定するので、「r」が登場する位置3を指定しています(図3に示すように、実は位置0のところにスペースが入っています)。

図3
図3

 oHellooWorldはどちらもテキストノードなので、これらのノードはこのレンジのstartContainerとendContainerに割り当てられます。これにより、startOffsetとendOffsetは、要素が渡されたときのように子ノードを探すのではなく、各ノードに含まれているテキストを探すようになります。commonAncestorContainerは、両方のノードを含んでいる最初の祖先である

要素になります。

 当然ながら、ドキュメントのセクションを選択しただけでは何の役にも立たないので、この選択範囲に対して何らかの操作を行うことになります。以降では、この点について説明します。

DOMレンジの内容の操作

 レンジを選択すると、内部的にドキュメントフラグメントノードが作成され、そこに選択内のすべてのノードがアタッチされます。ただし、この処理が行われる前に、選択内容が整形式であることが要求されます。

 先ほどの例に示したように、この方法では、途中に終了タグを含んでいる、「Hello」の1つ目の「l」から「World」の「o」までの範囲を選択することができます(図4を参照)。このような選択は、『Professional JavaScript for Web Developers』(Nicholas C. Zakas 著、Wrox Pr Inc.、2005年4月)で説明されている通常のDOMメソッドでは不可能です。

図4
図4

 レンジを使ったときにこの制限を回避できるのは、レンジでは欠けている開始タグと終了タグが認識されるからです。前述の例では、選択内に開始タグが足りないと判断されたため、レンジによって開始タグが動的に追加され、さらに「He」を閉じるための終了タグが新たに追加されます。これにより、DOMは次のようになります。

<p><b>Heb><b>llob> Worldp>

 このレンジに含まれるドキュメントフラグメントは図5のようになります。

図5
図5

 このドキュメントフラグメントが作成されると、レンジの内容をさまざまなメソッドで操作できるようになります。

 最もわかりやすく使いやすいのはdeleteContents()メソッドでしょう。このメソッドでは、レンジの内容をドキュメントから削除します。前述の例でレンジに対してdeleteContents()を呼び出すと、ページ内のHTMLは次のようになります。

<p><b>Heb>rldp>

 ドキュメントフラグメント全体が削除されるので、そのままだとタグが足りなくなりますが、レンジによってタグが補われるため、ドキュメントは整形式に保たれます。

 extractContents()メソッドはdeleteContents()によく似ています。このメソッドでは、選択範囲をドキュメントから削除し、その範囲のドキュメントフラグメントを戻り値として返します。これにより、そのレンジの内容を他の場所に挿入することが可能になります。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
var oFragment = oRange.extractContents();
document.body.appendChild(oFragment);

 この例では、ドキュメントフラグメントを抽出した後、ドキュメントの要素の末尾に追加しています((ドキュメントフラグメントをappendChild()に渡したときは、そのフラグメント自身ではなく、フラグメントの子だけが追加されるので注意してください)。この例を実行すると、ページの先頭にはHerldが、ページの末尾にはllo Woが配置されます。

 また、cloneContents()メソッドを使用すると、ドキュメントフラグメントをその場に残したまま、そのフラグメントのコピーを作成して、ドキュメントの他の場所に挿入することができます。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
var oFragment = oRange.cloneContents();
document.body.appendChild(oFragment);

 このメソッドはextractContents()によく似ています(どちらもレンジのドキュメントフラグメントを返します)。この例を実行すると、ページの末尾にllo Woが追加され、元のHTMLコードはそのまま残ります。

筆者注
 ドキュメントフラグメントとそのレンジ選択に対する変更は、上記のいずれかのメソッドが呼び出されるまでは発生しません。その時点までは、元のHTMLには何の変化もありません。

DOMレンジの内容の挿入

 前述の3つのメソッドでは、それぞれ異なる方法でレンジの情報を削除またはコピーしました。また別のメソッドを使用して、レンジに内容を追加することもできます。

 insertNode()メソッドでは、選択レンジの先頭にノードを挿入できます。たとえば、前のセクションで定義したレンジに次のHTMLコードを挿入することを考えてみましょう。

<span style="color: red">Inserted textspan>

 この処理は次のコードで実現できます。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
var oSpan = document.createElement("span");
oSpan.style.color = "red";
oSpan.appendChild(document.createTextNode("Inserted text"));

oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
oRange.insertNode(oSpan);

 このJavaScriptを実行すると、次のHTMLコードが生成されます。

<p id="p1"><b>He<span style="color: red">Inserted textspan>llob>
              Worldp>

 レンジ選択の前半部分である「Hello」の「llo」の直前にが挿入されていることに注目してください。また、元のHTMLで要素が追加も削除もされていないことに注意してください。これは、前のセクションで紹介したメソッドを使用していないからです。このテクニックは、役に立つ情報をページに挿入するときなどに利用できます(たとえば、新規ウィンドウで開くリンクを示すアイコンなど)。

 レンジに内容を挿入するだけでなく、surroundContents()メソッドを使用して、レンジを囲むように内容を挿入することもできます。このメソッドは、レンジの内容を囲むノードを引数として受け取ります。内部的には、次のような処理が行われます。

  1. レンジの内容が抽出されます(extractContents()と同様)。
  2. 元のドキュメント内で、レンジが置かれていた位置に指定のノードが挿入されます。
  3. ドキュメントフラグメントの内容が指定のノードに追加されます。

 この機能は、Webページ内の特定の単語を強調表示するときなどに役立ちます。次に例を示します。

var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
var oSpan = document.createElement("span");
oSpan.style.backgroundColor = "yellow";

oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
oRange.surroundContents(oSpan);

 このコードを実行すると、選択レンジの背景が黄色で強調表示されます。

DOMレンジの折りたたみ

 レンジを空にする(つまりドキュメントのどの部分も選択していない状態にする)には、レンジの折りたたみ(collapse)を行います。レンジの折りたたみは、テキストボックスの動作に似ています。テキストボックスにテキストが含まれている場合、マウスを使用して単語全体を強調表示することができます。しかし、もう一度マウスの左ボタンをクリックすると、選択が解除され、2つの文字の間にカーソルが置かれます。レンジの折りたたみを行うときは、ドキュメントのパーツ間の位置を指定します(具体的には、レンジ選択の先頭または末尾になります)。図6に、レンジの折りたたみを行ったときの様子を示します。

図6
図6

 レンジを折りたたむにはcollapse()メソッドを使用します。このメソッドは、折りたたみの方向を示すブール型の引数を1つ取ります。引数がtrueの場合はレンジの先頭に向けて折りたたみ、falseの場合はレンジの末尾に向けて折りたたみます。レンジが折りたたまれているかどうかを判別するには、collapsedプロパティを使用します。

oRange.collapse(true);      //collapse to the starting point
alert(oRange.collapsed);    //outputs "true"

 レンジが折りたたまれているかどうかのテストは、レンジ内の2つのノードが隣り合っているかどうかを確認するときに役立ちます。たとえば、次のようなHTMLコードがあるとします。

<p id="p1">Paragraph 1p><p id="p2">Paragraph 2p>

 このコードの正確な構造がわからない場合は(たとえばコードを自動生成した場合など)、次のようにしてレンジを作成してみます。

var oP1 = document.getElementById("p1");
var oP2 = document.getElementById("p2");
var oRange = document.createRange();
oRange.setStartAfter(oP1);
oRange.setStartBefore(oP2);
alert(oRange.collapsed);    //outputs "true"

 この例では、p1の末尾とp2の先頭の間に何もないので、作成したレンジは折りたたまれています。

DOMレンジの比較

 複数のレンジがある場合は、compareBoundaryPoints()メソッドを使用して、それらのレンジに共通の境界(開始または終了)が含まれていないかどうかを確認できます。このメソッドは2つの引数を取り、これらの引数で比較対象のレンジと比較方法を指定します。比較方法は次の定数値で指定します。

定数値定数名挙動
0START_TO_START1つ目のレンジの開始点と2つ目のレンジの開始点を比較します
1START_TO_END1つ目のレンジの開始点と2つ目のレンジの終了点を比較します
2END_TO_END1つ目のレンジの終了点と2つ目のレンジの終了点を比較します
3END_TO_START1つ目のレンジの終了点と2つ目のレンジの開始点を比較します

 compareBoundaryPoints()メソッドは、1つ目のレンジの境界点が2つ目のレンジの境界点よりも前にある場合は-1を返し、2つの境界点が等しい場合は0を返し、1つ目のレンジの境界点が2つ目のレンジの境界点よりも後にある場合は1を返します。

 次に例を示します。

var oRange1 = document.createRange();
var oRange2 = document.createRange();
var oP1 = document.getElementById("p1");
oRange1.selectNodeContents(oP1);
oRange2.selectNodeContents(oP1);
oRange2.setEndBefore(oP1.lastChild);
alert(oRange1.compareBoundaryPoints(Range.START_TO_START, oRange2));
    //outputs 0
alert(oRange1.compareBoundaryPoints(Range.END_TO_END, oRange2));
    //outputs 1;

 このコードでは、2つのレンジがどちらもselectNodeContents()のデフォルト値を使用しているので、2つの境界点がまったく同じ位置にあります。したがって、1つ目のcompareBoundaryPoints()メソッドは0を返します。しかし、oRange2については後からsetEndBefore()を使用して終了点を変更し、oRange1の終了点がoRange2の終了点よりも後に来るようにしているので(図7を参照)、2つ目のcompareBoundaryPoints()メソッドは1を返します。

図7
図7

DOMレンジの複製

 必要に応じて、cloneRange()メソッドを使用してレンジを複製することができます。このメソッドは、呼び出したレンジの正確な複製を作成します。

var oNewRange = oRange.cloneRange();

 新しいレンジには元のレンジとまったく同じプロパティが含まれており、これらのプロパティの値は、元のレンジに影響を与えずに修正できます。

クリーンアップ

 レンジを使い終わったら、detach()メソッドを呼び出してシステムリソースを解放することをお勧めします。これは必須の作業ではなく、参照されなくなったレンジは最終的にガベージコレクタによって回収されます。しかし、レンジを使い終わって不要になったらdetach()を呼び出すようにすると、余計なメモリを占有せずに済みます。

oRange.detach();
 この記事はNicholas C. Zakas著『Professional JavaScript for Web Developers』(Wrox, 2006, ISBN: 0-471-77778-1)の第10章「Advanced DOM Techniques」からの抜粋です。
 Copyright 2005 by WROX. All rights reserved. Reproduced here by permission of the publisher.

著者紹介

Nicholas C. Zakas(Nicholas C. Zakas)
Professional Ajax』(WROX, ISBN: 0-471-77778-1)および『Professional JavaScript for Web Developers』(WROX, ISBN: 0-7645-7908-8)の著者。


関連記事
  • Eclipse RCPを好きなスクリプト言語で拡張する
  • Facadeデザインパターンを利用したオブジェクト指向JavaScriptカレンダーの作成
  • インターネットアプリケーションの新しいフレームワーク「Guise」
  • JavaScriptでブラウザコマンドラインを実装する
  • Javascript だけで実現するグラフ作成ツール


  • 関連テーマ
  • ブラウザ


  • ★最新トップニュース
    国内 ウィルコム、WX330K に「管理者ロック」機能を追加した新色「シルバーメタリック」を発売画像のある記事(携帯・ワイヤレス 8月20日 17:50)
    ウィルコムおよびウィルコム沖縄は、2008年8月20日、京セラ製の電話機「WX330K」の新色として「シルバーメタリック」を、8月27日に発売すると発表した。
    国内 オンライン動画編集の「Sprasia」、“mixi OpenID”に対応(Webマーケティング 8月20日 17:40)
    株式会社スプラシアは2008年8月20日、同社が企画・運営する、Web 上で動画にエフェクト(特殊効果)を合成するオンライン動画編集サイト「Sprasia(スプラシア)」が、同日より提供開始となった「mixi OpenID」に対応したと発表した。
    国内 オムニチュア、Web 解析コンサルティングパッケージ「Omniture Fusion」を提供開始画像のある記事(Webマーケティング 8月20日 17:40)
    オムニチュア株式会社は、2008年8月20日、ビジネス課題解決、技術支援および業種別ノウハウをパッケージ化した、Web 解析初期導入コンサルティングパッケージ「Omniture Fusion」(オムニチュア フュージョン)の提供を開始した。
    国内 VRI が「VCR」サービスを開始、動画コンテンツの実際の再生回数などを測定(Webマーケティング 8月20日 17:40)
    VCR は、動画コンテンツをユーザーが PC 上で実際に再生した状況を測る、OTS(Opportunity To See)ベースで動画の視聴状況を測定するもの。
    国内 サイバー攻撃のビジネス化が加速、ラックが警告(Webテクノロジー 8月20日 17:40)
    ラックが2008年8月20日、日本国内におけるセキュリティ脅威に関する報告書を公開した。報告によると、サイバー攻撃のビジネス化が一段と進んでいるようだ。
    トピックス
    > オススメのIT系求人情報【毎週月曜日更新】
    footer_301.gif


    リサーチ
    > デイリーリサーチDLサイト
    > OnlineResearchPortal (リサーチデータバンク)
    > モバイルリサーチ with goo
    footer_301.gif
    キーワード
    > iPhone > Youtube
    > Google > モバイルノート
    > 半導体 > ウィルコム
    > テーマ一覧はこちら
    footer_301.gif
    セミナー情報
    > 第1回インターネットコムマーケティングセミナー「新規クライアントを効率的に獲得する Web マーケティング手法とは」(3月26日)多数のご参加ありがとうございました
    footer_301.gif
    デベロッパー
    > DevX
    > CodeGuru
    > developer.com
    footer_301.gif
    j.i.c.ブログ
    ブログ一覧
    データメーション 【データメーション】
    Vista の過ちは「Windows 7」に本当に生かされるのか?(8月20日)
    ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」 【ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」】
    「飲食サービス業でハッピーな世界を!!」/株式会社ケン・トゥエニ・ワン(8月20日)
    デスマーチからの脱却 【デスマーチからの脱却】
    30min. iPhoneアプリリリース(8月18日)
    エンジニアの独り言 【エンジニアの独り言】
    技術進歩の落とし穴!?誰のためにシステムを作っていますか?(8月18日)
    Skypeブログ出張版 【Skypeブログ出張版】
    パナソニックWiFiフォン購入でSkype1ヶ国プランプレゼント(8月13日)
    Graphic Design Forum 【Graphic Design Forum】
    いっぱい詰まった橋 (8月11日)
    footer_301.gif
    最新コラム一覧
    Eメールマーケティング事情 Eメールマーケティング事情

    メルマガからメールマーケティングへ(8月20日)
    日本と韓国のインターネットビジネス最新動向調査 日本と韓国のインターネットビジネス最新動向調査

    日本と韓国のEコマースサイト比較3―EC サイト(8月20日)
    e-Japan 先端テクノロジー解説 e-Japan 先端テクノロジー解説

    在宅勤務のすすめ〜雇用型テレワークの現場から〜(8月20日)
    百式のネットビジネス研究 百式のネットビジネス研究

    delicious でブックマークされたページでの全文検索を可能にする「delizzy」(8月20日)
    週刊-サイト別アクセス状況データ 週刊-サイト別アクセス状況データ

    ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(8月19日)
    SNSをビジネスに活用しよう SNSをビジネスに活用しよう

    タグにまつわる「ゆらぎ」と「ムラ」の問題を考える(8月19日)
    DevX DevX

    OpenOfficeでのXForms入門(8月19日)
    エンジニア転職ノウハウ開発室 エンジニア転職ノウハウ開発室

    SEって、パソコン越しの会話ばっかだよね?(8月19日)
    アイレップの SEM フロンティア アイレップの SEM フロンティア

    円滑に SEO を導入・実施するための組織体制を構築しよう(2)(8月19日)
    モバイルSEO@フラクタリスト モバイルSEO@フラクタリスト

    モバイル SEO を始める前に(8月18日)
    footer_301.gif
    専門チャンネル
    > セキュリティチャネル > テレコムチャネル
    > サーチエンジンウォッチ
    footer_301.gif
    海外のインターネットコム アメリカ韓国ドイツトルコ
    関連企業のサイト:ストックフォト イラスト ネットストリート ホテル予約サイト タウン情報 出張 事業継承 シミュレーション トランクルーム 優待映画チケット 田舎暮らしガイド オリジナルデザインTシャツ ニタコエ
    Copyright 2008 Jupitermedia Corporation All Rights Reserved. http://www.internet.com/
    space.gif space.gif