バリケンのJavaScript日記 RSSフィード

2006-11-10

[] DOMの要素の属性を変更する  DOMの要素の属性を変更する - バリケンのJavaScript日記 を含むブックマーク はてなブックマーク -  DOMの要素の属性を変更する - バリケンのJavaScript日記  DOMの要素の属性を変更する - バリケンのJavaScript日記 のブックマークコメント

昨日までは「DOMの要素の書き換え」をやってみたけど、今日は「DOMの要素の属性の変更」をやってみるよ。

じゃあ、画像クリックすると次の画像を表示するスライドショーを作ってみるよ。まずはテキストエディタを立ち上げて、htmlタグを書くよ。

<html>
</html>

次にheadタグbodyタグだね。

<html>
  <head>
  </head>
  <body>
  </body>
</html>

画像を表示させるのはimgタグだよ。表示されるのはbodyタグの部分だから、bodyタグの中に追加すればいいよね。

<html>
  <head>
  </head>
  <body>
    <img>
    </img>
  </body>
</html>

画像ファイルsrc属性で指定すれば表示されるはずだよね。

<html>
  <head>
  </head>
  <body>
    <img src="img001.jpg">
    </img>
  </body>
</html>

さらにid属性もつけて、JavaScriptから簡単に参照できるようにするよ。ついでにalt属性もつけて、画像が表示されなかったときの代替テキストも指定するよ。

<html>
  <head>
  </head>
  <body>
    <img id="img" alt="Photos" src="img001.jpg">
    </img>
  </body>
</html>

次はJavaScriptコーディングだね。scriptタグをheadタグの中に追加するよ。ついでにprototype.jsのロード部分も追加しよう。

<html>
  <head>
    <script language="JavaScript" type="text/javascript" src="prototype.js">
    </script>
    <script type="text/javascript">
    </script>
  </head>
  <body>
    <img id="img" alt="Photos" src="img001.jpg">
    </img>
  </body>
</html>

今回は「スライドショー」を作るから、「今何ページか、という状態」を保持した関数を実装したいよね。「状態を保持した関数」と言ったらクロージャが使えそうだよね。

まずは、引数に「画像ファイル名を列挙した配列」を与えると「引数で与えた数だけインデックスをずらした画像ファイル名を返す関数」を生成する関数makeChangePhotoを作ってみるよ。「関数を生成する関数」であることに注意してね。次のような感じになるよ。

function makeChangePhoto(photos) {
  var i = 0;
  function f (x) {
    i = (i + x) % photos.length;
    if (i < 0) i += photos.length;
    return photos[i];
  }
  return f;
}

次に、今回スライドさせる画像ファイルを列挙した配列引数としてmakeChangePhoto関数を実行して、生成した関数にphotoFileという変数名を付けるよ。

function makeChangePhoto(photos) {
  var i = 0;
  function f (x) {
    i = (i + x) % photos.length;
    if (i < 0) i += photos.length;
    return photos[i];
  }
  return f;
}
var photoFile = makeChangePhoto(["img001.jpg", "img002.jpg", "img003.jpg", "img004.jpg"]);

こうすれば、photoFile関数を1を引数として実行すれば「"img002.jpg"」が、さらにもう一回1を引数として実行すれば「"img003.jpg"」が返ってくるよ。配列の最後の要素まで行ったら、その次は配列の最初の要素に戻るよ。

そしていよいよ今日メイン、「DOMの要素の属性の変更」をやってみるよ。とは言っても属性の変更はとっても簡単、属性の名前をプロパティとして参照したり書き換えたりできるみたいだよ。今回は"img"というid属性を付けたimgタグsrc属性を指定したいんだけど、そのときは「$("img").src」って書けばいいみたい。

ということで、実際にsrc属性を書き換える部分を書いてみるよ。書き換える内容は、先ほど生成したphotoFile関数を呼び出すことで得るようにするよ。

function makeChangePhoto(photos) {
  var i = 0;
  function f (x) {
    i = (i + x) % photos.length;
    if (i < 0) i += photos.length;
    return photos[i];
  }
  return f;
}
var photoFile = makeChangePhoto(["img001.jpg", "img002.jpg", "img003.jpg", "img004.jpg"]);
function changePhoto(x) {
  $("img").src = photoFile(x);
}

あとはこの内容をscriptタグの中に書いて、imgタグのonclick属性に呼び出し関数を追加すればいいよね。せっかくだから普通クリックすると進んで、Ctrlを押しながらクリックすると戻るようにしてみたよ。

<html>
  <head>
    <script language="JavaScript" type="text/javascript" src="prototype.js">
    </script>
    <script type="text/javascript">
      function makeChangePhoto(photos) {
        var i = 0;
        function f (x) {
          i = (i + x) % photos.length;
          if (i < 0) i += photos.length;
          return photos[i];
        }
        return f;
      }
      var photoFile = makeChangePhoto(["img001.jpg", "img002.jpg", "img003.jpg", "img004.jpg"]);
      function changePhoto(x) {
        $("img").src = photoFile(x);
      }
    </script>
  </head>
  <body>
    <p>Click image!</p>
    <p>
      <img id="img" alt="Photos" src="img001.jpg" onclick="changePhoto(event.ctrlKey ? -1 : 1)">
      </img>
    </p>
  </body>
</html>

せっかくだから無料レンタルWebスペースを借りて、このhtmlファイルを置いてみたよ。

http://muscovyduck.kusakage.com/javascript/slideshow/

画像クリックすると画像が変わっていくのを試してみてね。

トラックバック - http://javascript.g.hatena.ne.jp/muscovyduck/20061110

2006-11-09

[] もうちょっと簡単にDOMの要素を変更する  もうちょっと簡単にDOMの要素を変更する - バリケンのJavaScript日記 を含むブックマーク はてなブックマーク -  もうちょっと簡単にDOMの要素を変更する - バリケンのJavaScript日記  もうちょっと簡単にDOMの要素を変更する - バリケンのJavaScript日記 のブックマークコメント

昨日の続きだよ。

昨日のさいごの状態のhello.htmは、次のような感じだったよね。

<html>
  <head>
    <script type="text/javascript">
      function changeWorld() {
        var helloElement = document.getElementById("hello");
        helloElement.replaceChild(document.createTextNode("Change the world!"),
                                  helloElement.childNodes[0]);
      }
    </script>
  </head>
  <body>
    <div id="hello" onclick="changeWorld()">Hello, world.</div>
  </body>
</html>

でもなんだかややこしいよねえ。もうちょっと簡単にならないかな?ということで、まずはややこしそうなreplaceChildメソッドの部分をどうにかしようと思うよ。

実は「要素オブジェクト(ここではhelloElement変数で参照する)の内容をHTMLであらわしたもの」は、innerHTMLプロパティで参照したり書き換えたりすることができるみたいだよ。つまり、

helloElement.replaceChild(document.createTextNode("Change the world!"),
                          helloElement.childNodes[0]);

は、

helloElement.innerHTML = "Change the world!";

のように書けるんだって。じゃあ、書き直してみよう!

<html>
  <head>
    <script type="text/javascript">
      function changeWorld() {
        var helloElement = document.getElementById("hello");
        helloElement.innerHTML = "Change the world!";
      }
    </script>
  </head>
  <body>
    <div id="hello" onclick="changeWorld()">Hello, world.</div>
  </body>
</html>

そしてさらに

var helloElement = document.getElementById("hello");
helloElement.innerHTML = "Change the world!";

と書いていたけど、helloElement変数を使わなくてもメソッドチェーンを使えば次のように一行で書けそうだよね。

document.getElementById("hello").innerHTML = "Change the world!";

じゃあ、書き直してみよう!

<html>
  <head>
    <script type="text/javascript">
      function changeWorld() {
        document.getElementById("hello").innerHTML = "Change the world!";
      }
    </script>
  </head>
  <body>
    <div id="hello" onclick="changeWorld()">Hello, world.</div>
  </body>
</html>

そしてさらにさらに、prototype.jsを使うと「document.getElementById("hello")」を「$("hello")」って書けるみたいだよ!すごいシンプル

prototype.jsを使うには、次のようにscriptタグで読み込んであげればいいみたいだよ。

<script language="JavaScript" type="text/javascript" src="prototype.js">
</script>

じゃあ、以上を踏まえて書き直してみるね。

<html>
  <head>
    <script language="JavaScript" type="text/javascript" src="prototype.js">
    </script>
    <script type="text/javascript">
      function changeWorld() {
        $("hello").innerHTML = "Change the world!";
      }
    </script>
  </head>
  <body>
    <div id="hello" onclick="changeWorld()">Hello, world.</div>
  </body>
</html>

うん、changeWorld関数の中身はずいぶんすっきりしたよね。

トラックバック - http://javascript.g.hatena.ne.jp/muscovyduck/20061109

2006-11-08

[] DOMの要素を変更する  DOMの要素を変更する - バリケンのJavaScript日記 を含むブックマーク はてなブックマーク -  DOMの要素を変更する - バリケンのJavaScript日記  DOMの要素を変更する - バリケンのJavaScript日記 のブックマークコメント

昨日の続きだよ。まずはとりあえずHTMLを書かないとね。例のごとく「Hello, world.」を表示するHTMLを書いてみよう。まずはテキストエディタを立ち上げて、htmlタグから書き始めるよ。

<html>
</html>

次にheadタグbodyタグを追加するよ。

<html>
  <head>
  </head>
  <body>
  </body>
</html>

表示されるのはbodyタグの部分だから、ここに「Hello, world.」と書けばいいよね。

<html>
  <head>
  </head>
  <body>
    Hello, world.
  </body>
</html>

じゃあ、いったんhello.htmというファイル名で保存して、ブラウザで表示してみよう!ちゃんと「Hello, world.」って表示されたよね?

次は、この「Hello, world.」を「ページの遷移なしで」変更してみるよ。まずは「変更したい部分」をひとまとまりにするために、divタグで囲むよ。

<html>
  <head>
  </head>
  <body>
    <div>Hello, world.</div>
  </body>
</html>

次に、divタグid属性をつけて、JavaScriptから簡単に参照できるようにするよ。

<html>
  <head>
  </head>
  <body>
    <div id="hello">Hello, world.</div>
  </body>
</html>

じゃあ、いよいよJavaScriptコーディングをするよ。JavaScriptコードscriptタグで囲む必要があるから、まずはscriptタグを追加するよ。scriptタグ記述するのはheadタグの中がいいみたい。

<html>
  <head>
    <script type="text/javascript">
    </script>
  </head>
  <body>
    <div id="hello">Hello, world.</div>
  </body>
</html>

Hello, world.」を変更する関数changeWorldを書いてみるよ。

<html>
  <head>
    <script type="text/javascript">
      function changeWorld() {
      }
    </script>
  </head>
  <body>
    <div id="hello">Hello, world.</div>
  </body>
</html>

DOMオブジェクトは、とくになにも宣言しなくてもdocumentという変数を使って参照できるよ。さらに便利なことに、DOMオブジェクトにはあらかじめ便利なメソッドがいくつか定義されているよ。

DOMオブジェクトから特定の「要素オブジェクト」を取り出すには、getElementByIdメソッドを使うみたい。引数には、さっきdiv要素に追加したidを指定するよ。

<html>
  <head>
    <script type="text/javascript">
      function changeWorld() {
        var helloElement = document.getElementById("hello");
      }
    </script>
  </head>
  <body>
    <div id="hello">Hello, world.</div>
  </body>
</html>

「要素オブジェクト」にも、やっぱりあらかじめ便利なメソッドがいくつか定義されているみたい。さっき取り出した「要素オブジェクト」の内容を書き換えるには、replaceChildメソッドを使えばいいみたいだよ。

<html>
  <head>
    <script type="text/javascript">
      function changeWorld() {
        var helloElement = document.getElementById("hello");
        helloElement.replaceChild();
      }
    </script>
  </head>
  <body>
    <div id="hello">Hello, world.</div>
  </body>
</html>

replaceChildメソッドを使って要素オブジェクトの内容を置き換えるには、「新しい要素オブジェクト」と「古い要素オブジェクトの場所」を順番に引数で指定してあげればいいみたい。「新しい要素オブジェクト」はcreateTextNodeメソッドで作って、「古い要素オブジェクトの場所」はchildNodesプロパティ(これは配列だよ)で指定するよ。

<html>
  <head>
    <script type="text/javascript">
      function changeWorld() {
        var helloElement = document.getElementById("hello");
        helloElement.replaceChild(document.createTextNode("Change the world!"),
                                  helloElement.childNodes[0]);
      }
    </script>
  </head>
  <body>
    <div id="hello">Hello, world.</div>
  </body>
</html>

これでchangeWorld関数ができたけど、何らかの方法で呼び出さないとね。じゃあ、要素をクリックした時にこの関数が呼び出されるように、divにonclick要素を追加するよ。

<html>
  <head>
    <script type="text/javascript">
      function changeWorld() {
        var helloElement = document.getElementById("hello");
        helloElement.replaceChild(document.createTextNode("Change the world!"),
                                  helloElement.childNodes[0]);
      }
    </script>
  </head>
  <body>
    <div id="hello" onclick="changeWorld()">Hello, world.</div>
  </body>
</html>

じゃあ、hello.htmという名前で保存したら、ブラウザで開いて試してみよう!「Hello, world.」をクリックすると「Change the world!」に変わることを確認してね。

2006-11-07

[] DOMって何?  DOMって何? - バリケンのJavaScript日記 を含むブックマーク はてなブックマーク -  DOMって何? - バリケンのJavaScript日記  DOMって何? - バリケンのJavaScript日記 のブックマークコメント

DOM」ってよくわかってないから、勉強してみることにするよ。

DOMとは、Document Object Modelの略なんだって。WebブラウザHTML(もしくはXHTML)をHTTPによって受け取ると、表示するときにいったんXMLドキュメントに変換するんだって。そのXMLで表現しているオブジェクトのことをDOMって呼ぶみたいだよ。

つまり、DOMとは「いまWebブラウザで表示している画面」を表わすオブジェクトのことなんだね。

今見ているページのDOMXMLで表現したものを見るためのツールを「DOMインスペクタ」って言うみたいだよ。たとえばFirefoxの場合のDOMインスペクタのインストール方法はこちらにあるみたいだよ。他のブラウザ用のDOMインスペクタもあるはずだから、探してみてね。

そして面白いことに、今見ているページのDOMを何らかの手段で書き換えれば、即座に画面に反映されるんだって。パソコンの画面をメモリで表現する「VRAM」に似ているねえ。

じゃあ、明日からは「JavaScriptDOMをいじって動的に画面を変更する」実験をしてみることにするよ。

トラックバック - http://javascript.g.hatena.ne.jp/muscovyduck/20061107

2006-11-05

[] JavaScriptでの継承  JavaScriptでの継承 - バリケンのJavaScript日記 を含むブックマーク はてなブックマーク -  JavaScriptでの継承 - バリケンのJavaScript日記  JavaScriptでの継承 - バリケンのJavaScript日記 のブックマークコメント

いまいちまだ理解してない「JavaScriptでの継承」について、「技術日記@kiwanami - JavaScriptでの継承について調べてみた」というエントリの説明が良さそうだよ。あとでじっくり読みたいなあ。

トラックバック - http://javascript.g.hatena.ne.jp/muscovyduck/20061105