A ppendix JavaScript の サンプル 集 すぐに 使 える 便 利 なサンプル 集 です 01 実 用 的 な 入 力 チェックを 行 なう 02 パスワードの 入 力 チェックを 即 時 実 行 する 03 サムネイル 画 像 のサイズを 切 り 替 える 04 JavaScriptが 有 効 かどうかをチェックする 05 テーブルの 特 定 行 を 強 調 する 06 入 力 中 のテキストボックスの 背 景 色 を 変 える 07 ローディング 画 面 を 表 示 する 08 長 い 文 章 を 省 略 し 続 きを 読 む リンクを 表 示 する 09 金 額 をカンマ 区 切 りで 表 示 する 10 開 閉 式 のメニューを 作 る 11 自 動 的 に 隠 れるナビゲーションメニューを 作 る 12 ページトップへ 戻 るボタンを 表 示 する 13 スクロールで 画 像 がめくれる 動 きを 表 現 する 14 ドアが 開 くようなアニメーションを 表 現 する 15 アバター 機 能 を 作 る 16 タブメニューを 作 る 17 サムネイル 画 像 付 きのスライドショーを 作 る 18 ループするスライドショーを 作 る 19 一 定 時 間 おきに 自 動 で 動 くスライドショーを 作 る
Appendix Tips 実 用 的 な 01 入 力 チェックを 行 なう 難 易 度 フォームの 入 力 チェック 方 法 は 第 9 章 のリスト9.5(222ページ)で 紹 介 し ました しかし エラーメッセージをダイアログボックスで 表 示 する 方 法 はあ まり 実 用 的 とは 言 えませんので ここではエラーメッセージをページ 上 に 表 示 する 方 法 を 紹 介 します また スクリプトは jqueryを 利 用 して 記 述 します 実 行 結 果 HTML 01.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main01.js"></script> </head> <body> <!-- --> <div id="errorarea"></div> 2
Tips01 実 用 的 な 入 力 チェックを 行 なう <form name="frm1" action="xxx"> <fieldset> <legend> </legend> <label> <input type="text" name="lastname"> </label> <label> <input type="text" name="firstname"> </label> </fieldset> <fieldset> <legend> </legend> <label> <input type="radio" name="gender" value="m"> </label> <label> <input type="radio" name="gender" value="f"> </label> </fieldset> <input type="button" id="sendbtn" value=" "> </form> </body> </html> JavaScript main01.js 01: $(function(){ 02: $("#sendbtn").on("click", inputcheck); 03: ); 04: function inputcheck(){ 05: var errors = []; 06: 07: if(!$("input[name='lastname']").val()) { 08: errors.push(" "); 09: 10: if (!$("input[name='firstname']").val()) { 11: errors.push(" "); 12: 13: if (!$("input[name='gender']:checked").val()) { 14: errors.push(" "); 15: 16: 17: if(errors.length > 0) { 18: $("#errorarea").html(errors.join("<br>")); 19: else { 20: $("form[name='frm1']").submit(); 21: 22: 3
Appendix [ 送 信 ]ボタンがクリックされると inputcheck 関 数 が 実 行 されます まず 5 行 目 でerrorsに 空 の 配 列 を 代 入 しています errorsはエラーメッセージを 保 持 する 配 列 です 発 生 したエラーの 件 数 分 配 列 の 要 素 が 追 加 されます 7 行 目 から9 行 目 にかけて 姓 が 入 力 されているかどうかをチェックしていま す テキストボックスが 未 入 力 の 場 合 valメソッドは 空 文 字 ("")を 返 します JavaScriptでは 空 文 字 はfalseとして 判 定 されます 条 件 式 の 先 頭 に! 演 算 子 が 付 いているので 姓 が 未 入 力 の 場 合 にifブロック 内 が 実 行 され 配 列 errors にエラーメッセージが 追 加 されます 姓 が 未 入 力 の 場 合 if(!$("input[name='lastname']").val()) { テキストボックスに 入 力 された 文 字 列 を 取 得 if(!"") { 空 文 字 はfalse として 解 釈 される if(!false) { 論 理 値 を 反 転 if(true) { 10 行 目 から12 行 目 も 前 述 の 処 理 と 同 様 のチェックを 行 なっています 13 行 目 では オプションボタン(ラジオボタン)がチェックされているか どうかを 調 べています チェックされているオプションボタンが 存 在 しない 場 合 セレクタに 該 当 する 要 素 は 存 在 しません よってvalメソッドを 実 行 して も undefined が 返 却 されます undefinedも 空 文 字 と 同 様 falseとして 扱 わ れます 17 行 目 から21 行 目 では 3つのチェック 項 目 でエラーが 発 生 したかどうかを 調 べています エラーが 発 生 しているときは 配 列 errorsに1 件 以 上 のエラー メッセージが 追 加 されています その 場 合 複 数 のエラーメッセージ 群 を<br> で 区 切 って1つの 文 字 列 として 連 結 し エラー 表 示 エリアに 挿 入 しています 4
Tips02 パスワードの 入 力 チェックを 即 時 実 行 する Tips パスワードの 入 力 02 チェックを 即 時 実 行 する 難 易 度 先 のサンプルのようにボタンを 押 したタイミングではなく テキストボック スに 文 字 列 を 入 力 すると 即 座 にチェックする 方 法 を 紹 介 します 例 として パ スワードの 文 字 列 長 文 字 種 強 度 をチェックします 実 行 結 果 HTML 02.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main02.js"></script> </head> <body> <input type="text" id="password"> <p id="message"></p> </body> </html> 5
Appendix JavaScript main02.js 01: $(function() { 02: $("#password").on("keyup", inputcheck); 03: ); 04: function inputcheck() { 05: var errors = []; 06: var password = $("#password").val(); 07: 08: if(password.length < 8 password.length > 12) { 09: errors.push(" 8 12 "); 10: 11: if(password.match(/[^0-9a-za-z]/)) { 12: errors.push(" "); 13: 14: if(!(password.match(/[0-9]/) && password. match(/[a-z]/) && password.match(/[a-z]/))) { 15: errors.push(" "); 16: 17: 18: $("#message").html(errors.join("<br>")); 19: テキストボックス 上 で 文 字 列 が 入 力 されたタイミングで 処 理 を 実 行 するに は keyupイベントを 使 います keyupは キーボードから1 文 字 分 の 入 力 が 行 なわれた 際 に 実 行 されるイベントです 8 行 目 では 文 字 列 長 をチェックしています lengthプロパティは 配 列 の 場 合 は 要 素 数 でしたが 文 字 列 の 場 合 は 文 字 列 の 長 さを 表 わします 11 行 目 では 文 字 種 をチェックしています 以 下 の 正 規 表 現 は 半 角 英 数 字 以 外 の 文 字 にマッチするかどうかを 調 べています [ ] の 先 頭 に ^ を 付 けると 以 降 のパターンと 一 致 しない 文 字 にマッチします password.match(/[^0-9a-za-z]/) 0-9 a-z A-Z 以 外 の 文 字 が 含 まれているかどうか 14 行 目 では パスワードの 強 度 をチェックしています 本 来 強 度 チェック では 1234 などの 単 純 な 文 字 列 もはじかなければなりませんが 今 回 は 簡 易 6
Tips02 パスワードの 入 力 チェックを 即 時 実 行 する 版 として 大 文 字 小 文 字 数 字 の3 種 類 がすべて 含 まれていることのみを 条 件 としています 以 下 のif 文 は 3 種 の 文 字 すべてが 含 まれている という 条 件 を 否 定 しています if(!(password.match(/[0-9]/) && password.match(/[a-z]/) && password.match(/[a-z]/))) { 数 字 が 含 まれる 小 文 字 が 含 まれる 大 文 字 が 含 まれる どれか1つでも 満 たさなければfalse 全 体 が! 演 算 子 で 囲 まれているので 論 理 値 が 反 転 され true となる 7
Appendix す Tips サムネイル 画 像 の 03 サイズを 切 り 替 える 難 易 度 オプションボタンで 選 択 されたサイズに 応 じて 画 像 の 拡 大 率 を 変 更 しま 実 行 結 果 8
Tips03 サムネイル 画 像 のサイズを 切 り 替 える HTML 03.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main03.js"></script> <link rel="stylesheet" type="text/css" href="style03.css"> </head> <body> <div> <input type="radio" name="size" value="small" checked> <input type="radio" name="size" value="medium"> <input type="radio" name="size" value="large"> </div> <div id="photo"> <img src="images/frog1.jpg" class="small"> <img src="images/frog2.jpg" class="small"> <img src="images/frog3.jpg" class="small"> </div> </body> </html> CSS style03.css.small { width: 50px;.medium { width: 100px;.large { width: 150px; JavaScript main03.js 01: $(function() { 02: $("input[name='size']").on("change", changesize); 03: ); 04: function changesize() { 05: $("#photo > img").removeclass(); 06: $("#photo > img").addclass($("input[name='size']: checked").val()); 07: 9
Appendix オプションボタンの 選 択 状 態 が 変 更 されると changesize 関 数 が 実 行 されま す まず 5 行 目 で 全 画 像 から 現 在 設 定 されているCSSクラスを 削 除 し 初 期 化 しています 次 に6 行 目 で 3 つあるオプションボタンのうち 現 在 選 択 中 のオプションボタン の value 属 性 値 を 取 得 し 全 画 像 に 対 し 同 名 のCSSクラスを 適 用 しています 例 ラジオボタンで 大 を 選 択 している 場 合 1 大 のvalue 属 性 値 である "large" が 取 得 される $("#photo > img").addclass($("input[name='size']:checked").val()); 2 画 像 に 対 してCSSクラス "large" が 適 用 される "large" $("#photo > img").addclass("large"); 10
Tips04 JavaScript が 有 効 かどうかをチェックする Tips JavaScriptが 有 効 か 04 どうかをチェックする 難 易 度 JavaScriptはブラウザの 設 定 で 無 効 にすることが 可 能 です 必 ずJavaScript を 動 作 させたいページでは ユーザーにスクリプトの 有 効 化 を 促 すメッセージ を 表 示 すると 良 いでしょう 実 行 結 果 JavaScriptが 有 効 な 場 合 JavaScriptが 無 効 な 場 合 11
Appendix HTML 04.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script> alert(" "); </script> </head> <body> <noscript>javascript </noscript> </body> </html> <noscript>タグは スクリプトが 動 作 しない 場 合 に 表 示 する 内 容 を 定 義 する タグです スクリプトが 有 効 になっている 場 合 <noscript>タグは 無 視 されま す 12
Tips05 テーブルの 特 定 行 を 強 調 する Tips テーブルの 特 定 行 を 05 強 調 する 難 易 度 テーブルの 各 行 のうち 特 定 の 文 字 列 を 含 む 行 を 強 調 表 示 します 例 とし て 会 員 名 簿 の 中 でゴールド 会 員 の 行 を 強 調 します 実 行 結 果 HTML 05.html <!DOCTYPE html> <html lang="ja"> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main05.js"></script> <link rel="stylesheet" type="text/css" href="style05.css"> </head> <body> <h1> </h1> <table id="userlist"> 13
Appendix <tr> <th>no</th> <th> </th> <th> </th> </tr> <tr> <td>1</td> <td> </td> <td> </td> </tr> <tr> <td>2</td> <td> </td> <td> </td> </tr> <tr> <td>3</td> <td> </td> <td> </td> </tr> <tr> <td>4</td> <td> </td> <td> </td> </tr> <tr> <td>5</td> <td> </td> <td> </td> </tr> </table> </body> </html> CSS style05.css table, th, td { padding: 0px 10px; border-collapse: collapse; /* */ border: solid 1px black; /* 1px */.highlight { background-color: blue; color: white; 14
Tips05 テーブルの 特 定 行 を 強 調 する JavaScript main05.js 01: $(function(){ 02: $("#userlist tr:contains(' ')").addclass("highlight"); 03: ); テーブルの 各 行 のうち "ゴールド"という 文 字 列 を 含 む 行 のみ 抽 出 し 強 調 表 示 用 のCSSクラス"highlight"を 適 用 しています 15
Appendix Tips 入 力 中 のテキストボックス 06 の 背 景 色 を 変 える 難 易 度 現 在 カーソルが 当 たっている 要 素 がどれであるかわかりやすく 見 せるため に 入 力 中 のテキストボックスの 背 景 色 を 変 えて 強 調 表 示 します 実 行 結 果 HTML 06.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main06.js"></script> </head> <body> <input type="text" name="text1"> <input type="text" name="text2"> <input type="text" name="text3"> </body> </html> 16
Tips06 入 力 中 のテキストボックスの 背 景 色 を 変 える JavaScript main06.js 01: $(function() { 02: $("input[type='text']").on("focus", function() { 03: $(this).css("background-color", "pink"); 04: ); 05: $("input[type='text']").on("blur", function() { 06: $(this).css("background-color", "white"); 07: ); 08: ); 各 テキストボックスにカーソルが 当 たったタイミングで 実 行 されるfocusイ ベントで 背 景 色 にピンクを 設 定 し カーソルが 外 れたタイミングで 実 行 される blurイベントで 背 景 色 を 白 に 戻 しています $(this)で 取 得 した 要 素 に 対 してス タイルを 適 用 しているので イベントの 発 生 元 であるテキストボックスにのみ 背 景 色 が 設 定 されます 17
Appendix Tips ローディング 画 面 を 07 表 示 する 難 易 度 Ajaxによるデータの 取 得 など ページの 表 示 までに 時 間 がかかる 処 理 を 実 行 する 場 合 に 読 込 中 であることを 表 わすローディング 画 面 を 表 示 します 第 13 章 で 紹 介 したリスト13.3(331ページ)のツイッター APIを 利 用 するサンプルに データの 取 得 中 はローディング 画 面 を 表 示 する 処 理 を 追 加 します 使 用 する 画 像 ローディング 画 像 (loading.png) 実 行 結 果 データ 取 得 中 データ 取 得 完 了 後 18
Tips07 ローディング 画 面 を 表 示 する HTML 07.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main07.js"></script> <link rel="stylesheet" type="text/css" href="style07.css"> </head> <body> <!-- --> <div id="wall"><img src="images/loading.png" class="loading"></div> <table> <tr> <th> </th> <th> </th> <th> </th> <th> </th> </tr> </table> </body> </html> CSS style07.css * { margin: 0; padding: 0; /* */ #wall { /* */ position: fixed; width: 100%; height: 100%; background-color: gray; /* */.loading { /* */ position: absolute; width: 160px; 19
Appendix height: 150px; top: 50%; left: 50%; margin-top: -75px; margin-left: -80px; JavaScript main07.js 01: $(function() { 02: $("#wall").show(); 03: var q = encodeuricomponent(" "); 04: $.getjson("http://search.twitter.com/search. json?callback=?&q=" + q, 05: function(data) { 06: for(var i=0; i<data.results.length; i++) { 07: $("table").append( 08: "<tr>" + 09: "<td><img src='" + data.results[i]. profile_image_url + "'></td>" + 10: "<td>@" + data.results[i].from_user + "</td>" + 11: "<td>" + data.results[i].from_user_name + "</td>" + 12: "<td>" + data.results[i].text + "</td>" + 13: "</tr>" 14: ); 15: // for 16: $("#wall").hide(); 17: // 18: ); 19: 20: ); Ajax 通 信 の 実 行 前 にローディング 画 面 を 表 示 し データの 取 得 が 完 了 したら ローディング 画 面 を 非 表 示 にする 処 理 を 行 なっています 取 得 完 了 後 のタイミ ングで 非 表 示 処 理 を 行 なうには getjson 関 数 の 引 数 であるコールバック 関 数 の 中 に 処 理 を 記 述 します ローディング 画 像 が 回 転 したりするアニメーションを 付 けたい 場 合 は 画 像 をGIFアニメーション( 複 数 のGIFファイルをつなぎ 合 わせた 形 式 )にしてお きます 20
Tips08 長 い 文 章 を 省 略 し 続 きを 読 む リンクを 表 示 する Tips 長 い 文 章 を 省 略 し 続 き 08 を 読 む リンクを 表 示 する 難 易 度 最 初 は 記 事 の 一 部 のみを 表 示 しておき リンクをクリックすることで 全 文 が 表 示 される ブログなどでよく 見 られる 機 能 を 作 成 します 実 行 結 果 初 期 表 示 続 きを 読 む をクリック 後 HTML 08.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> 21
Appendix <script src="main08.js"></script> </head> <body> <p id="content"> </p> <!-- --> <p id="omittext"></p> <a href="javascript:void(0)" rel="all"> </a> </body> </html> JavaScript main08.js 01: $(function() { 02: // 03: $("#content").hide(); 04: // 20 05: var omit = $("#content").text().slice(0, 20); 06: // 07: $("#omittext").text(omit); 08: $("a[rel='all']").on("click", showall); 09: ); 10: function showall() { 11: // 12: $(this).hide(); 13: // 14: $("#omittext").hide(); 15: // 16: $("#content").show(); 17: HTML 文 書 にはあらかじめ 記 事 全 文 を 記 述 しておき 初 期 表 示 時 に 全 文 の 非 表 示 化 と 省 略 記 事 の 抽 出 / 表 示 処 理 を 行 ないます 5 行 目 で 記 事 の 先 頭 から 20 文 字 分 の 文 字 列 を 抽 出 しています textメソッドはhtmlメソッドと 同 様 に 要 素 の 内 容 を 取 得 しますが 内 容 に 含 まれるタグは 除 外 されます 続 きを 読 む リンククリック 時 の 処 理 は showall 関 数 で 行 なっています リンクと 省 略 記 事 を 隠 し 記 事 全 文 を 表 示 して 初 期 表 示 時 と 逆 の 表 示 状 態 に しています 22
Tips08 長 い 文 章 を 省 略 し 続 きを 読 む リンクを 表 示 する なお 続 きを 読 む リンクのHTMLは 以 下 のように 定 義 されています <a href="javascript:void(0)" rel="all"> </a> <a>タグのhref 属 性 に"javascript:void(0)"を 指 定 すると <a>タグのリンク 機 能 が 無 効 化 されます リンククリック 時 にリンク 先 ページの 表 示 ではなく JavaScriptによる 処 理 を 実 行 したい 場 合 は href 属 性 にこの 記 述 を 入 れておく 必 要 があります 23
Appendix Tips 金 額 をカンマ 区 切 りで 09 表 示 する 難 易 度 数 字 のみで 入 力 された 金 額 を 3 桁 ごとにカンマで 区 切 って 表 示 します カ ンマ 表 記 への 変 換 は 正 規 表 現 を 使 って 行 ないます 実 行 結 果 24 HTML 09.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main09.js"></script> </head> <body> <input type="text" id="price"> <input type="button" id="btn" value=" "> </body> </html>
Tips09 金 額 をカンマ 区 切 りで 表 示 する JavaScript main09.js 01: $(function(){ 02: $("#btn").on("click", convert); 03: ); 04: function convert(){ 05: var price = $("#price").val(); 06: while (price.match(/([0-9]+)([0-9]{3)/)) { 07: price = price.replace(/([0-9]+)([0-9]{3)/, "$1,$2"); 08: 09: $("#price").val(price); 10: [ 変 換 ]ボタンがクリックされると convert 関 数 が 実 行 されます 5 行 目 で 入 力 された 金 額 を 取 得 し 変 数 priceに 代 入 しています テキストボックスの 入 力 値 は 必 ず 文 字 列 型 として 取 得 されます 6 行 目 から8 行 目 が カンマ 表 記 への 変 換 を 行 なっている 箇 所 です 6 行 目 のwhile 文 の 継 続 条 件 式 は priceの 値 が 正 規 表 現 にマッチしている 間 繰 り 返 しを 続 けるという 意 味 です この 正 規 表 現 のパターンは 1 文 字 以 上 の 数 字 列 と 3 文 字 の 数 字 列 が 隣 接 している ということを 表 わしています price.match(/[0-9]+[0-9]{3/) 1 文 字 以 上 の 数 字 列 3 文 字 の 数 字 列 続 いて7 行 目 では 金 額 にカンマを 挿 入 しています replaceメソッドでは 正 規 表 現 の 後 方 参 照 という 機 能 を 利 用 できます 後 方 参 照 とは パターン 文 字 列 のうち 丸 かっこ()で 囲 んだ 部 分 を 置 換 文 字 列 として 利 用 できる 機 能 で す price.replace(/([0-9]+)([0-9]{3)/, "$1,$2") 1234567 という 数 字 列 が 入 力 された 場 合 を 例 とすると 最 初 の 繰 り 返 しで は 1234と567 がパターンにマッチし 1234,567 に 置 き 換 えられます 25
Appendix price.replace(/([0-9]+)([0-9]{3)/, "$1,$2") 1234,567 1234 567 1234,567 全 体 がマッチ 2 回 目 の 繰 り 返 しでは priceの 値 は 1234,567 になっているので パター ンにマッチするのは 1と234 で マッチした 箇 所 が 1,234 に 置 き 換 えられ ます price.replace(/([0-9]+)([0-9]{3)/, "$1,$2") 1234,567 1 234 1,234 1234 がマッチ これを 繰 り 返 していくことで 最 終 的 にパターンにマッチする 箇 所 がなくなり 3 桁 おきにカンマが 挿 入 された 文 字 列 が 完 成 する 仕 組 みとなっています 26
Tips10 開 閉 式 のメニューを 作 る Tips 10 開 閉 式 のメニューを 作 る 難 易 度 開 閉 ボタンをクリックするたびに メニューを 展 開 / 折 り 畳 みします 使 用 する 画 像 開 くボタン 閉 じるボタン (open.png)(close.png) 実 行 結 果 初 期 表 示 フードメニューを 開 く ドリンクメニューを 開 く 27
Appendix HTML 10.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main10.js"></script> </head> <body> <div class="menu"> <img src="images/open.png" name="open"> <img src="images/close.png" name="close"> <ul> <li> </li> <li> </li> <li> </li> </ul> </div> <div class="menu"> <img src="images/open.png" name="open"> <img src="images/close.png" name="close"> <ul> <li> </li> <li> </li> <li> </li> </ul> </div> </body> </html> 28 JavaScript main10.js 01: $(function() { 02: // 03: $(".menu ul").hide(); 04: // 05: $(".menu img[name='close']").hide(); 06: $(".menu img").on("click", visiblechange); 07: ); 08: function visiblechange() { 09: // 10: $(this).parent().children().toggle(); 11:
Tips10 開 閉 式 のメニューを 作 る まず 初 期 表 示 時 にメニューと 閉 じるボタンを 隠 します フードとドリンク の2つのメニューがあるので 両 方 の 要 素 をセレクタで 取 得 し 一 括 で 非 表 示 化 を 行 なう 処 理 を2 5 行 目 で 行 なっています ボタンがクリックされたときは visiblechange 関 数 が 実 行 されます 10 行 目 の 処 理 は メニュー 一 覧 および 開 閉 ボタンの 表 示 状 態 を 切 り 替 える 処 理 で す parent()は 対 象 要 素 の 親 要 素 を 取 得 します また children()は 要 素 が 持 つ 子 要 素 をすべて 取 得 します 10: $(this).parent().children().toggle(); イベントの 発 生 元 ( 開 閉 ボタン) 開 閉 ボタンの 親 <div> の 子 要 素 要 素 (<div>) (<img> 2 <ul>) 表 示 / 非 表 示 の 切 り 替 え 初 期 表 示 時 の 状 態 ( 濃 い 網 掛 けの 要 素 は 非 表 示 ) <div class="menu"> <img src="images/open.png" name="open"> <img src="images/close.png" name="close"> <ul> <li> </li> <li> </li> <li> </li> </ul> </div> <div class="menu"> <img src="images/open.png" name="open"> <img src="images/close.png" name="close"> <ul> <li> </li> <li> </li> <li> </li> </ul> </div> 29
Appendix フードメニュー の 開 くボタンがクリックされた 場 合 の 実 行 順 序 <div class="menu"> 1 $(this) <img src="images/open.png" name="open"> 2 parent() <img src="images/close.png" name="close"> 3 children() <ul> <li> </li> <li> </li> 4 3 つの 要 素 に <li> </li> 対 して toggle() </ul> を 実 行 </div> フードメニュー の 開 くボタンクリック 後 の 状 態 ( 濃 い 網 掛 けの 要 素 は 非 表 示 ) <div class="menu"> <img src="images/open.png" name="open"> <img src="images/close.png" name="close"> <ul> <li> </li> <li> </li> <li> </li> </ul> </div> <div class="menu"> <img src="images/open.png" name="open"> <img src="images/close.png" name="close"> <ul> <li> </li> <li> </li> <li> </li> </ul> </div> 30
Tips11 自 動 的 に 隠 れるナビゲーションメニューを 作 る Tips 自 動 的 に 隠 れるナビゲー 11 ションメニューを 作 る 難 易 度 マウスポインタの 位 置 に 応 じて ウィンドウ 上 部 に 表 示 されるナビゲーショ ンメニューの 表 示 状 態 を 切 り 替 えます 実 行 結 果 ウィンドウ 上 部 から30px 未 満 にマウスポインタがある 場 合 ウィンドウ 上 部 から30px 以 降 にマウスポインタがある 場 合 HTML 11.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> 31
Appendix <script src="main11.js"></script> <link rel="stylesheet" type="text/css" href="style11.css"> </head> <body> <div id="nav"> <ul> <li>top</li> <li>news</li> <li>gallery</li> <li>contact</li> </ul> </div> </body> </html> CSS style11.css * { margin: 0; padding: 0; #nav { position: fixed; /* */ width: 100%; height: 30px; background-color: blue; color: white; #nav ul{ list-style-type: none; /* */ #nav li { float: left; /* */ padding: 5px 20px; JavaScript main11.js 01: $(function() { 02: $("#nav").hide(); 03: $(window).on("mousemove", shownaviarea); 04: ); 05: function shownaviarea(e) { 06: if($("#nav").is(':hidden') && e.clienty < 30) { 07: $("#nav").slidedown(500); 08: else if($("#nav").is(':visible') && e.clienty >= 30){ 09: $("#nav").slideup(500); 10: 11: 32
Tips11 自 動 的 に 隠 れるナビゲーションメニューを 作 る マウスが 動 いたときに 処 理 を 行 なうには mousemoveイベントを 利 用 しま す 3 行 目 で ウィンドウ 上 でマウスポインタが 動 かされたときのイベントを 設 定 しています $(window).on("mousemove", shownaviarea); ウィンドウ 全 体 を 表 わす イベントが 発 生 すると shownaviarea 関 数 が 実 行 されます mousemove イベント 発 生 時 の 処 理 は 引 数 としてマウスポインタの 座 標 情 報 を 受 け 取 りま す 横 方 向 の 座 標 はclientXプロパティ 縦 方 向 の 座 標 はclientYプロパティに 入 っています 6 7 行 目 で ナビゲーションメニューをアニメーション 付 きで 表 示 する 処 理 を 行 なっています 表 示 条 件 は ナビゲーションメニューが 非 表 示 の 状 態 でか つ 縦 方 向 の 座 標 が 30px 未 満 の 場 合 です isメソッドは 対 象 の 要 素 がセレク タ 書 式 で 記 述 した 条 件 に 一 致 する 場 合 にtrueを 返 します 6: if($("#nav").is(':hidden') && e.clienty < 30) { ナビゲーションメニューが 非 表 示 状 態 かどうか マウスポインタの 縦 位 置 が 上 から 30px 未 満 かどうか 8 9 行 目 は ナビゲーションメニューが 表 示 状 態 でかつ 縦 方 向 の 座 標 が 30px 以 上 の 場 合 にナビゲーションメニューを 隠 す 処 理 です 8: else if($("#nav").is(':visible') && e.clienty >= 30){ ナビゲーションメニューが 表 示 状 態 かどうか マウスポインタの 縦 位 置 が 上 から 30px 以 降 かどうか 33
Appendix Tips ページトップへ 戻 る 12 ボタンを 表 示 する 難 易 度 ウィンドウを 下 にスクロールしたときに ページの 先 頭 へ 戻 るための 画 像 ボ タンを 表 示 します スクロールしていない 状 態 ではボタンは 表 示 しません 使 用 する 画 像 ページの 背 景 画 像 (fish.jpg) 戻 るボタン(top.png) 実 行 結 果 34 ページトップ スクロールした 状 態
Tips12 ページトップへ 戻 るボタンを 表 示 する HTML 12.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main12.js"></script> <link rel="stylesheet" type="text/css" href="style12.css"> </head> <body> <img src="images/top.png" id="topbtn"> </body> </html> CSS style12.css body { height: 500px; background-image: url("images/fish.jpg"); /* */ #topbtn { /* */ position: fixed; right: 10px; bottom: 10px; JavaScript main12.js 01: $(function(){ 02: $("#topbtn").hide(); 03: $("#topbtn").on("click", gototop); 04: $(window).on("scroll", showtopbtn); 05: ); 06: function showtopbtn() { 07: if($(window).scrolltop() > 0) { 08: $("#topbtn").show(); 09: else { 10: $("#topbtn").hide(); 11: 12: 13: function gototop() { 14: $("html,body").animate({ "scrolltop" : "0", 300); 15: $("#topbtn").hide(); 16: 35
Appendix まず 初 期 表 示 時 に 実 行 される 処 理 から 見 てみましょう 01: $(function(){ 02: $("#topbtn").hide(); 03: $("#topbtn").on("click", gototop); 04: $(window).on("scroll", showtopbtn); 05: ); 初 期 状 態 では 戻 るボタンは 表 示 しないので 2 行 目 で 非 表 示 処 理 を 行 なって います 3 行 目 と4 行 目 では 戻 るボタンクリック 時 のイベントとウィンドウス クロール 時 のイベントを 登 録 しています スクロールイベントは <window> 要 素 に 対 して 設 定 します 続 いて ウィンドウスクロール 時 に 実 行 されるshowTopbtn 関 数 です 06: function showtopbtn() { 07: if($(window).scrolltop() > 0) { 08: $("#topbtn").show(); 09: else { 10: $("#topbtn").hide(); 11: 12: showtopbtn 関 数 は 戻 るボタンの 表 示 状 態 を 制 御 します <window> 要 素 のscrollTopメソッドは 現 在 のスクロール 位 置 をピクセル 値 で 表 わします ページの 先 頭 を 表 示 している 場 合 scrolltop()が 返 す 値 は0となります この 関 数 では ウィンドウが 下 にスクロールされていれば 戻 るボタンを 表 示 し 未 スクロールの 状 態 では 戻 るボタンを 非 表 示 にする 処 理 を 行 なっています 最 後 に 戻 るボタンクリック 時 に 実 行 されるgotoTop 関 数 です 13: function gototop() { 14: $("html,body").animate({ "scrolltop" : "0", 300); 15: $("#topbtn").hide(); 16: 36
Tips12 ページトップへ 戻 るボタンを 表 示 する gototop 関 数 は 現 在 の 位 置 からページの 先 頭 までアニメーション 付 きで 移 動 する 処 理 を 行 ないます animateメソッドでscrolltopの 値 を 操 作 する 場 合 は <html> 要 素 と<body> 要 素 に 対 して 処 理 を 実 行 します <window> 要 素 に 対 してアニメーションを 実 行 してもうまく 動 作 しないので 気 をつけましょう 37
Appendix Tips スクロールで 画 像 が 13 めくれる 動 きを 表 現 する 難 易 度 あらかじめ 画 像 を2 枚 重 ねて 配 置 しておき ウィンドウを 下 にスクロールし たときに 前 面 の 画 像 がめくれて 背 面 の 画 像 が 見 えるような 動 作 を 実 現 しま す 使 用 する 画 像 高 さは 300px 前 面 の 画 像 (frog1.jpg) 背 面 の 画 像 (frog2.jpg) 画 像 の 配 置 イメージ 実 行 結 果 ページトップ 途 中 までスクロールした 状 態 下 までスクロールした 状 態 38
Tips13 スクロールで 画 像 がめくれる 動 きを 表 現 する HTML 13.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main13.js"></script> <link rel="stylesheet" type="text/css" href="style13.css"> </head> <body> <div id="over"><img src="images/frog1.jpg"></div> <div id="under"><img src="images/frog2.jpg"></div> </body> </html> CSS style13.css body { height: 2000px; /* */ div { /* */ position: fixed; left: 0px; top: 0px; height: 300px; /* */ /* frog2.jpg <div> */ #under { z-index: 1; /* */ /* frog1.jpg <div> */ #over { z-index: 2; /* */ overflow: hidden; 39
Appendix JavaScript main13.js 01: $(function(){ 02: $(window).on("scroll", peeloff); 03: ); 04: function peeloff() { 05: var scroll = $(window).scrolltop(); 06: var height = $("#over img").height(); 07: $("#over").css("height", height-scroll); 08: 2つの 画 像 はそれぞれ<div>タグで 囲 まれていて 前 面 の 画 像 を 囲 む<div> 要 素 には"over" 背 面 の 画 像 を 囲 む<div> 要 素 には"under"というIDが 付 けら れています <div> 要 素 は 左 上 に 固 定 表 示 するようにCSSで 設 定 しているため 2つの 画 像 はどちらも 同 じ 座 標 上 に 配 置 されていることになります div { /* */ position: fixed; left: 0px; top: 0px; height: 300px; /* */ 各 <div> 要 素 には それぞれz-indexを 指 定 しています z-indexは 重 なり 順 を 設 定 するプロパティです 数 値 が 大 きいほど 前 面 に 数 値 が 小 さいほど 背 面 に 表 示 されます また 前 面 の 画 像 を 囲 む<div> 要 素 にはoverflow: hidden; が 設 定 されている ため <div> 要 素 の 枠 からはみ 出 た 部 分 は 非 表 示 となります #under { z-index: 1; /* */ #over { 40
Tips13 スクロールで 画 像 がめくれる 動 きを 表 現 する z-index: 2; /* */ overflow: hidden; スクリプトの 内 容 は 単 純 です ウィンドウがスクロールされると peeloff 関 数 が 実 行 されます peeloff 関 数 では 前 面 の 画 像 を 囲 む<div> 要 素 の 高 さを 変 化 させる 処 理 を 行 なっています <div> 要 素 の 高 さは 画 像 の 高 さ スク ロール 量 で 求 めることができます なお 6 行 目 のheightメソッドは 要 素 の 高 さを 数 値 型 で 取 得 するメソッドです 05: var scroll = $(window).scrolltop(); 06: var height = $("#over img").height(); 07: $("#over").css("height", height-scroll); <div> 要 素 の 高 さは 画 像 と 同 じ 300px 140px 分 スクロールした 場 合 300px 140px=160px を <div> 要 素 の 高 さとして 設 定 する 前 面 の <div> 要 素 の 高 さが 減 った 分 背 面 の 画 像 が 見 えるようになる 41
Appendix Tips ドアが 開 くような 14 アニメーションを 表 現 する 難 易 度 ある 画 像 の 前 面 に2 枚 の 扉 画 像 を 重 ねて 配 置 しておき どちらかの 扉 画 像 を クリックするとドアが 左 右 に 開 いていくように 見 える 動 作 を 実 現 します 使 用 する 画 像 幅 は400px 背 面 の 画 像 (frog1.jpg) 幅 は 200px 前 面 の 画 像 (left.png と right.png) 画 像 の 配 置 イメージ 実 行 結 果 初 期 表 示 42
Tips14 ドアが 開 くようなアニメーションを 表 現 する 扉 画 像 をクリックするとドアが 開 くような 動 作 をする HTML 14.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main14.js"></script> <link rel="stylesheet" type="text/css" href="style14.css"> </head> <body> <div class="door"> <img src="images/frog1.jpg" id="photo"> <img src="images/left.png" id="left"> <img src="images/right.png" id="right"> </div> </body> </html> 43
Appendix CSS style14.css body { padding: 20px; /* 3 */.door { position: relative; width: 400px; left: 200px;.door img { /* <div> */ position: absolute; top: 0px; #photo { z-index: 1; /* */ left: 0px; #left { z-index: 2; /* */ left: 0px; /* */ #right { z-index: 2; /* */ left: 200px; /* */ JavaScript main14.js 01: $(function(){ 02: $("#left,#right").on("click", opendoor); 03: ); 04: function opendoor() { 05: $("#left").animate({"left" : "-200px", 400); 06: $("#right").animate({"left" : "400px", 400); 07: 写 真 の 前 面 に 左 右 の 扉 画 像 が2 枚 配 置 されています 扉 画 像 はそれぞれ 親 の<div> 要 素 の 左 上 を 基 準 とした 相 対 位 置 に 配 置 されています 44
Tips14 ドアが 開 くようなアニメーションを 表 現 する 色 付 き 枠 部 分 が 親 の <div> 要 素 0px 200px 扉 画 像 のどちらかがクリックされると 左 の 扉 画 像 は 親 の<div> 要 素 の 左 端 から-200pxの 位 置 へ 右 の 扉 画 像 は 親 の<div> 要 素 の 左 端 から400pxの 位 置 へ 移 動 します 色 付 き 枠 部 分 が 親 の <div> 要 素 -200px 0px 400px 45
Appendix Tips 15 アバター 機 能 を 作 る 難 易 度 アバター 画 像 に 対 して ユーザーが 選 択 した 服 を 着 せる 機 能 を 実 装 します アバター 画 像 の 前 面 に 同 じ 大 きさの 着 替 え 画 像 を 重 ねることで 服 を 着 ている ように 見 せることができます 使 用 する 画 像 160px 140px アバター 画 像 (human.png) 着 替 え 画 像 (plain.png / star.png / heart.png) 大 きさはアバター 画 像 と 同 じ 服 の 周 りの 余 白 は 透 過 色 アバター 画 像 着 替 え 画 像 ともに 実 際 の 画 像 には 枠 は 付 いていません 画 像 の 配 置 イメージ 46
Tips15 アバター 機 能 を 作 る 実 行 結 果 選 択 した 服 に 着 せ 替 える 初 期 表 示 着 替 え 画 像 をクリック HTML 15.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main15.js"></script> <link rel="stylesheet" type="text/css" href="style15.css"> </head> <body> <!-- --> <div id="avatar"> <img src="images/human.png" id="human"> </div> <!-- --> <div id="clothes"> <img src="images/plain.png"> <img src="images/star.png"> <img src="images/heart.png"> </div> </body> </html> 47
Appendix CSS style15.css /* */ #avatar { position: relative; width: 140px; height: 160px; margin: 10px auto; /* */ #avatar img { position: absolute; top: 0px; left: 0px; /* */ #clothes { white-space: nowrap; /* */ #clothes img { width: 100px; /* */ border: solid 1px black; JavaScript main15.js 01: $(function() { 02: $("#clothes img").on("click", changeclothes); 03: ); 04: function changeclothes() { 05: $("#avatar img:not(#human)").remove(); 06: $("#avatar").append($(this).clone()); 07: 着 せ 替 え 画 像 一 覧 のうちいずれかをクリックすると changeclothes 関 数 が 実 行 されます まず アバター 画 像 を 初 期 化 する 処 理 を 行 ないます 5 行 目 で は アバター 表 示 エリアから アバター 画 像 以 外 の 画 像 をすべて 削 除 していま す remove()は 対 象 の 要 素 を 削 除 するメソッドです これにより すでにアバ ターに 服 が 着 せられている 場 合 も 裸 の 状 態 に 戻 ります 48
Tips15 アバター 機 能 を 作 る 05: $("#avatar img:not(#human)").remove(); 1 アバター 表 示 エリアのうち IDが"human" の 画 像 以 外 を 取 得 2 取 得 した 画 像 を 削 除 続 いて 6 行 目 で 選 択 された 画 像 を 複 製 し アバター 表 示 エリアに 追 加 して います clone()は 対 象 の 要 素 のコピーを 生 成 するメソッドです 06: $("#avatar").append($(this).clone()); 3 アバター 表 示 エリアの 末 尾 に 追 加 1 クリックされ た 画 像 を 取 得 2 画 像 を 複 製 複 数 の 要 素 が 同 じ 座 標 に 配 置 される 場 合 後 ろに 挿 入 された 要 素 ほど 前 面 に 表 示 されます よってこのサンプルではz-indexで 重 ね 順 を 指 定 する 必 要 はあ りません 49
Appendix Tips 16 タブメニューを 作 る 難 易 度 タブメニューのクリックにより 対 応 するコンテンツを 表 示 します 同 時 に 現 在 アクティブなタブが 最 前 面 に 表 示 されているような 視 覚 効 果 を 表 現 しま す 実 行 結 果 50
Tips16 タブメニューを 作 る HTML 16.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main16.js"></script> <link rel="stylesheet" type="text/css" href="style16.css"> </head> <body> <div id="tabarea"> <div id="top" class="tab active"> <span>top</span> </div> <div id="about" class="tab"> <span>about</span> </div> <div id="access" class="tab"> <span>access</span> </div> </div> <!-- --> <div id="content"> <div id="content-top"> Web </div> <div id="content-about" class="hidden"> </div> <div id="content-access" class="hidden"> 10 </div> </div> </body> </html> CSS style16.css #content { width: 400px; height: 100px; padding: 20px; margin-top: 1px; /* 1px */ border: solid 1px black; z-index: 1; /* */ #tabarea { 51
Appendix height: 30px; white-space: nowrap; z-index: 2; /* */.tab { width: 80px; height: 30px; padding-left: 10px; display: inline-block; /* */ border: solid 1px black; border-radius: 5px 5px 0 0; /* */ background-color: white; cursor: pointer; /* */.active { border-bottom: solid 1px white; /* */.tab span { line-height: 30px; /* 1 */.hidden { display: none; JavaScript main16.js 01: $(function() { 02: $("#tabarea.tab").on("click", tabchange); 03: ); 04: function tabchange() { 05: // 06: $("#tabarea.tab").removeclass("active"); 07: $("#content div").hide(); 08: 09: // 10: $(this).addclass("active"); 11: var id = $(this).attr("id"); 12: $("#content-" + id).show(); 13: タブは <div> 要 素 のまわりにCSS で 線 を 引 いて 作 成 します 52
Tips16 タブメニューを 作 る.tab { width: 80px; height: 30px; padding-left: 10px; display: inline-block; /* */ border: solid 1px black; border-radius: 5px 5px 0 0; /* */ background-color: white; cursor: pointer; /* */ <div> 要 素 に "tab" クラスを 適 用 した 状 態 現 在 選 択 中 のアクティブなタブは 下 線 のみ 白 で 描 画 します.active { border-bottom: solid 1px white; /* */ <div> 要 素 に "tab" クラスと "active" クラスを 適 用 した 状 態 同 様 に コンテンツ 表 示 エリアも<div> 要 素 のまわりに 線 を 引 いて 作 成 しま す 線 は 要 素 の 外 側 に 描 画 されるため <div> 要 素 が 隣 接 している 場 合 は 線 が 重 なり 合 って 表 示 されます この 微 妙 なズレを 調 整 するために コンテンツ 表 示 エリアの 上 に 余 白 をとっ て 1px 分 下 にずらします 53
Appendix さらに z-indexプロパティでタブをコンテンツ 表 示 エリアの 前 面 に 重 なる ように 指 定 します タブに"active"クラスが 指 定 されている 場 合 は 下 線 が 白 で 表 示 されるため タブとコンテンツ 表 示 エリアを 区 切 る 線 が 隠 れ 1 枚 のつな がった 紙 のように 見 えます #content { width: 400px; height: 100px; padding: 20px; margin-top: 1px; /* 1px */ border: solid 1px black; z-index: 1; /* */ #tabarea { height: 30px; white-space: nowrap; z-index: 2; /* */ 各 タブがクリックされると tabchange 関 数 が 実 行 されます まず 6 行 目 と7 行 目 では 全 タブから"active"クラスを 削 除 し 各 コンテンツを 非 表 示 にする 初 期 化 処 理 を 行 なっています 10 行 目 では イベントの 発 生 元 であるタブに 対 して"active"クラスを 適 用 し ています 11 行 目 12 行 目 ではイベント 発 生 元 のタブが 持 つID 値 を 取 得 し タブに 対 応 するコンテンツを 表 示 しています 54
Tips16 タブメニューを 作 る about タブがクリックされた 場 合 <div id="tabarea"> <div id="top" class="tab active"> <span>top</span> </div> <div id="about" class="tab"> <span>about</span> </div> <div id="access" class="tab"> <span>access</span> </div> </div> <!-- --> <div id="content"> イベントの 発 生 元 "content-" + タブの ID が 対 応 するコンテンツ <div id="content-top"> Web </div> <div id="content-about" class="hidden"> </div> <div id="content-access" class="hidden"> 10 </div> </div> 55
Appendix Tips サムネイル 画 像 付 きの 17 スライドショーを 作 る 難 易 度 第 14 章 のリスト14.8(355ページ)で 作 成 したスライドショーを 改 造 して サムネイル 一 覧 の 中 から 選 択 した 画 像 まで 一 気 に 移 動 する 機 能 を 作 成 します 実 行 結 果 選 択 した 画 像 に スライドする HTML 17.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main17.js"></script> <link rel="stylesheet" type="text/css" href="style17.css"> </head> 56
Tips17 サムネイル 画 像 付 きのスライドショーを 作 る <body> <!-- --> <div id="photoframe"> <div id="imagearea"></div> </div> <!-- --> <div id="naviarea"></div> </body> </html> CSS style17.css * { margin: 0; padding: 0; #photoframe { position: relative; width: 200px; height: 150px; left: 50%; margin: 30px 0px 30px -100px; /* */ overflow: hidden; /* */ #imagearea { position: absolute; left: 0px; width: 1000px; height: 150px; white-space: nowrap; #imagearea img { width: 200px; height: 150px; /* */ #naviarea { position: relative; width: 400px; left: 50%; margin-left: -200px; /* */ white-space: nowrap; #naviarea img{ width: 80px; 57
Appendix JavaScript main17.js 01: $(function() { 02: var imagearea = $("#imagearea"); // 03: var naviarea = $("#naviarea"); // 04: 05: // 06: for(var i=1; i<=5; i++) { 07: imagearea.append("<img src='images/flower" + i + ".jpg'>"); 08: naviarea.append("<img src='images/flower" + i + ".jpg'>"); 09: 10: 11: // 12: $("#naviarea img").on("click", moveimagearea); 13: ); 14: function moveimagearea() { 15: var imagearea = $("#imagearea"); 16: // 17: var src = $(this).attr("src"); 18: // 19: var targetposition = imagearea.find( "img[src='" + src + "']").position().left * -1; 20: // 21: imagearea.animate({"left" : targetposition, 500); 22: まず 6 9 行 目 で スライドショー 表 示 エリアとサムネイル 画 像 表 示 エリア の 両 方 にまったく 同 じ 画 像 を5 件 挿 入 しています サムネイル 画 像 表 示 エリアのいずれかの 画 像 がクリックされると move ImageArea 関 数 が 実 行 されます 17 行 目 では 選 択 されたサムネイル 画 像 のsrc 属 性 を 取 得 しています 19 行 目 で 同 じsrc 属 性 が 設 定 されている 画 像 をスライドショー 表 示 エリアの 中 から 検 索 し 画 像 の 左 位 置 を 取 得 しています リスト14.8では 左 位 置 をcss メソッドで 取 得 していましたが 今 回 その 方 法 は 使 えません cssメソッド は CSSで 明 示 的 にプロパティを 指 定 している 場 合 にのみ 有 効 です スライド ショー 表 示 エリアにはleftプロパティが 設 定 されていますが その 中 の<img> 要 素 1つ1つには 設 定 していないので cssメソッドでleftプロパティを 取 得 す ると 返 却 される 値 は"auto"になります このような 場 合 positionというメソッ ドを 利 用 します position()は 親 要 素 に 対 する 要 素 の 相 対 位 置 を 取 得 します 58
Tips17 サムネイル 画 像 付 きのスライドショーを 作 る プロパティとして top と left があり 位 置 情 報 を 数 値 型 で 保 持 しています flower3.pngが 選 択 された 場 合 を 例 として 解 説 します imagearea.find("img[src='" + src + "']").position().left * -1; クリックされたサムネイル 画 像 の src 属 性 値 imagearea.find("img[src='images/flower3.png']").position().left * -1; スライドショー 表 示 エリアの 中 から flower3.png を 表 示 している img 要 素 を 取 得 最 後 にposition().leftで 取 得 した 左 位 置 に 対 して-1を 掛 けています これはスラ イドショー 表 示 エリアのleftプロパティとして 設 定 すべき 値 を 算 出 する 処 理 です 初 期 表 示 時 imageareaのleftは0pxに 設 定 されています flower3.pngを 表 示 領 域 であるphotoFrame 内 に 配 置 するには flower3.png のleftを0pxの 位 置 に 移 動 しなければなりません そのためには スライド ショー 表 示 エリアのleftを-400pxに 設 定 する 必 要 があるのです このようにして 算 出 した 位 置 までスライドショー 表 示 エリアをanimateメ ソッドで 移 動 させることで 指 定 画 像 まで 一 気 にスライドさせる 処 理 を 実 現 し ています 59
Appendix Tips ループする 18 スライドショーを 作 る 難 易 度 第 14 章 のリスト14.8(355ページ)で 作 成 したスライドショーを 画 像 がルー プして 表 示 されるように 改 造 します 実 行 結 果 flower5.jpg flower1.jpg 次 へ 前 へ HTML 18.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main18.js"></script> <link rel="stylesheet" type="text/css" href="style18.css"> </head> <body> <div id="photoframe"> 60
Tips18 ループするスライドショーを 作 る <div id="imagearea0" class="imagearea"></div> <div id="imagearea1" class="imagearea"></div> </div> <div> <button id="prev"> </button> <button id="next"> </button> </div> </body> </html> CSS style18.css * { margin: 0; padding: 0; body { padding: 30px; #photoframe { position: relative; width: 200px; height: 150px; overflow: hidden;.imagearea { position: absolute; width: 1000px; height: 150px; white-space: nowrap; #imagearea0 { left: -1000px; #imagearea1 { left: 0px; img { width: 200px; height: 150px; 61
Appendix JavaScript main18.js 01: var currentindex = 1; 02: 03: $(function() { 04: var photoframe = $("#photoframe"); 05: for(var i=1; i<=5; i++) { 06: photoframe.find(".imagearea").append( "<img src='images/flower" + i + ".jpg'>"); 07: 08: 09: $("#next").on("click", function() { 10: todisabled(); 11: photoframe.find(".imagearea").animate( 12: {"left" : "-=200px", "fast", "linear", next); 13: ); 14: 15: $("#prev").on("click", function() { 16: todisabled(); 17: photoframe.find(".imagearea").animate( 18: {"left" : "+=200px", "fast", "linear", prev); 19: ); 20: ); 21: 22: function next() { 23: // imagearea 24: var otherindex = 1 - currentindex; 25: if(parseint($("#imagearea" + currentindex). css("left")) == -800) { 26: // 27: // imagearea left photoframe 28: $("#imagearea" + otherindex).css("left", "200px"); 29: 30: else if(parseint($("#imagearea" + currentindex). css("left")) == -1000) { 31: // imagearea 32: currentindex = otherindex; 33: 34: toenabled(); 35: 36: 37: function prev() { 38: // imagearea 39: var otherindex = 1 - currentindex; 40: if(parseint($("#imagearea" + currentindex). css("left")) == 0) { 41: // 42: // imagearea left photoframe 43: $("#imagearea" + otherindex).css("left", "-1000px"); 44: 62
Tips18 ループするスライドショーを 作 る 45: else if(parseint($("#imagearea" + currentindex). css("left")) == 200) { 46: // imagearea 47: currentindex = otherindex; 48: 49: toenabled(); 50: 51: 52: function todisabled() { 53: $("#prev, #next").attr("disabled", "disabled"); 54: 55: 56: function toenabled() { 57: $("#prev, #next").removeattr("disabled"); 58: スライドショーのループを 実 現 するには imagearea(5 件 分 の 画 像 を 囲 む <div> 要 素 )を2つ 用 意 します 末 尾 の 画 像 あるいは 先 頭 の 画 像 を 表 示 した タイミングで 隠 れているほうのimageAreaのleftプロパティを 操 作 し 左 右 のどちらかに 移 動 します 以 下 のような 実 行 イメージになります [ 次 へ]ボタンがクリックされて 末 尾 の 画 像 が 表 示 されたとき 63
Appendix [ 前 へ]ボタンがクリックされて 先 頭 の 画 像 が 表 示 されたとき まず あらかじめHTML 文 書 にimageAreaを2 つ 用 意 しておきます IDは それぞれimageArea0とimageArea1としています 末 尾 の0と1は それぞれ を 識 別 するためのインデックスとして 利 用 します また 両 方 に 同 じクラス 名 を 設 定 しているので 2つまとめて 操 作 することもできます <div id="photoframe"> <div id="imagearea0" class="imagearea"></div> <div id="imagearea1" class="imagearea"></div> </div> CSSでは 各 imageareaのleftプロパティに 初 期 位 置 を 設 定 しています 最 初 はimageArea0をphotoFrame( 可 視 領 域 )の 左 側 に 隠 し imagearea1の 1 番 目 の 画 像 が 表 示 されるように 配 置 します #imagearea0 { left: -1000px; #imagearea1 { left: 0px; 64
Tips18 ループするスライドショーを 作 る 各 imageareaの 初 期 位 置 以 降 現 在 表 示 されているほうのimageAreaのことを カレントimage Area と 表 現 します カレントとは 現 在 の という 意 味 です それでは JavaScriptのコードを 順 に 追 っていきましょう まず 1 行 目 ではグローバル 変 数 currentindexを 宣 言 し 初 期 値 としてカレ ントimageAreaのインデックスを 代 入 しています 01: var currentindex = 1; 4 7 行 目 でimageAreaの 親 要 素 であるphotoFrameを 取 得 し 子 要 素 の imageareaに 画 像 をロードしています imageareaは2つあるので 両 方 に まったく 同 じ5 件 分 の<img> 要 素 が 挿 入 されます 03: $(function() { 04: var photoframe = $("#photoframe"); 05: for(var i=1; i<=5; i++) { 06: photoframe.find(".imagearea").append( "<img src='images/flower" + i + ".jpg'>"); 07: 9 ~ 13 行 目 は [ 次 へ]ボタンクリック 時 の 処 理 です アニメーション 完 了 後 にnext 関 数 を 実 行 します 15 ~ 19 行 目 は [ 前 へ]ボタンクリック 時 の 処 理 で こちらはアニメーショ ン 完 了 後 にprev 関 数 を 実 行 します 続 いて このサンプルの 胆 の 部 分 であるimageAreaの 移 動 処 理 を 行 なう next 関 数 を 見 ていきましょう 65
Appendix 22: function next() { 23: // imagearea 24: var otherindex = 1 - currentindex; まず 24 行 目 で 隠 れているほうの imagearea のインデックスを 取 得 していま す インデックスは 以 下 の 計 算 式 によって 算 出 することが 可 能 です 隠 れているほうの imagearea のインデックスを 求 める 計 算 式 1 - imagearea Hint 計 算 式 の 考 え 方 カレントのインデックスが1の 場 合 隠 れているほうのインデックスは 0 カレントのインデックスが0の 場 合 隠 れているほうのインデックスは 1 カレントのインデックスを 反 転 させれば もう 一 方 のインデックスを 得 ることが できる 実 際 にimageAreaを 移 動 する 処 理 は 25 ~ 29 行 目 のifブロック 内 で 行 なっ ています 25: if(parseint($("#imagearea" + currentindex). css("left")) == -800) { 26: // 27: // imagearea left photoframe 28: $("#imagearea" + otherindex).css("left", "200px"); 29: if 文 の 条 件 式 では カレントimageAreaの 末 尾 の 画 像 を 表 示 しているかどう かを 判 定 しています 次 のように 変 数 を 使 って 記 述 することで 動 的 にセレク タを 生 成 できます 66
Tips18 ループするスライドショーを 作 る カレントimageArea のインデックスが 1 の 場 合 $("#imagearea" + currentindex) 1 $("#imagearea1") 末 尾 の 画 像 を 表 示 している 場 合 カレントimageAreaのleftは-800pxです このときに 隠 れているほうのimageAreaを 右 側 に 移 動 します photoframe ( 可 視 領 域 )の 右 側 に 配 置 するためには leftに200pxを 設 定 します 末 尾 の 画 像 を 表 示 しているときの 配 置 隠 れているほうのimageArea を 移 動 した 後 の 配 置 画 像 が 末 尾 に 達 するたびにこの 処 理 を 繰 り 返 すことにより あたかも 画 像 が 延 々とつながっているかのように 見 せることができるのです また next 関 数 ではcurrentIndexの 値 を 変 更 する 処 理 も 行 なっています 30: else if(parseint($("#imagearea" + currentindex). css("left")) == -1000) { 31: // imagearea 32: currentindex = otherindex; 33: 30 ~ 33 行 目 のelse if 文 では カレントimageAreaがphotoFrame( 可 視 領 域 ) から 外 れたタイミングで 今 まで 隠 れていたほうをカレントに 設 定 し 直 しています 67
Appendix カレントimageArea が photoframe から 外 れたときの 配 置 [ 前 へ]ボタンをクリックしたときのprev 関 数 もほぼ 同 じことを 行 なってい ます 相 違 点 は leftプロパティの 設 定 値 のみです 37: function prev() { 38: // imagearea 39: var otherindex = 1 - currentindex; 40: if(parseint($("#imagearea" + currentindex). css("left")) == 0) { 41: // 42: // imagearea left photoframe 43: $("#imagearea" + otherindex).css("left", "-1000px"); 44: 45: else if(parseint($("#imagearea" + currentindex). css("left")) == 200) { 46: // imagearea 47: currentindex = otherindex; 48: 49: toenabled(); 50: Hint より 良 いコードの 記 述 方 法 next 関 数 とprev 関 数 は leftプロパティの 設 定 値 が 異 なるだけで まったく 同 じ 処 理 を 行 なっています 見 た 目 にはわかりやすいのですが 実 はこのような 冗 長 なスクリプトはあまり 好 ましくありません なんらかの 変 更 を 加 えようとしたとき に 両 方 の 関 数 を 修 正 しなければならなくなるため メンテナンス 性 が 劣 るのです 改 善 例 としては まず 関 数 を1つにまとめ 引 数 で 次 へ 前 へ のどちらの 処 理 なのかを 示 す 値 を 受 け 取 ります leftプロパティの 設 定 値 群 は あらかじめ 変 数 や 配 列 に 保 持 しておき 引 数 に 応 じて 適 切 なほうを 選 択 します 画 像 の 数 を 増 やしても 動 作 するように 画 像 のwidthプロパティを 元 にしてleftプロパティ の 設 定 値 を 動 的 に 算 出 できれば さらに 良 いスクリプトになるでしょう なお animateメソッドのコールバック 関 数 は 関 数 名 または 関 数 式 の 形 式 でな ければ 記 述 できないため 引 数 を 渡 す 場 合 は 関 数 呼 び 出 しを 匿 名 関 数 で 内 包 する 必 要 があります 詳 しくは 第 10 章 の 引 数 のある 関 数 をイベントハンドラに 設 定 する (246ページ)を 参 考 にしてください 68
Tips19 一 定 時 間 おきに 自 動 で 動 くスライドショーを 作 る Tips 一 定 時 間 おきに 自 動 で 19 動 くスライドショーを 作 る 難 易 度 Tips18のループするスライドショーのサンプルを ボタンクリックではな く5 秒 おきに 自 動 で 画 像 が 流 れるように 改 造 します 実 行 結 果 flower1.jpg flower2.jpg 5 秒 後 HTML 19.html [ 前 へ][ 次 へ]ボタンを 削 除 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>javascript </title> <script src="http://ajax.googleapis.com/ajax/libs/ jquery/1.9.1/jquery.min.js"></script> <script src="main19.js"></script> <link rel="stylesheet" type="text/css" href="style18.css"> </head> <body> <div id="photoframe"> 69
Appendix <div id="imagearea0" class="imagearea"></div> <div id="imagearea1" class="imagearea"></div> </div> <div> <button id="prev"> </button> <button id="next"> </button> </div> </body> </html> CSS style18.css 変 更 なし 70 JavaScript main19.js 網 掛 けの 箇 所 が 変 更 点 01: $(function() { 02: var photoframe = $("#photoframe"); 03: for(var i=1; i<=5; i++) { 04: photoframe.find(".imagearea").append( "<img src='images/flower" + i + ".jpg'>"); 05: 06: 07: // 5 08: setinterval(slide, 5000); 09: // 10: ); 11: 12: function slide() { 13: $("#photoframe").find(".imagearea").animate( 14: {"left" : "-=200px", "fast", "linear", next); 15: 16: 17: currentindex = 1; 18: 19: function next() { 20: // imagearea 21: var otherindex = 1 - currentindex; 22: if(parseint($("#imagearea" + currentindex). css("left")) == -800) { 23: // 24: // imagearea left photoframe 25: $("#imagearea" + otherindex).css("left", "200px"); 26: 27: else if(parseint($("#imagearea" + currentindex). css("left")) == -1000) { 28: // imagearea 29: currentindex = otherindex; 30: 31: // toenabled(); 32: 33: //
Tips19 一 定 時 間 おきに 自 動 で 動 くスライドショーを 作 る 前 述 のサンプルとの 相 違 点 は 次 へ ボタンクリック 時 の 処 理 をsetInterval メソッドで 定 期 実 行 している 点 です これにより ユーザーが 何 も 操 作 しなく ても 一 定 間 隔 で 画 像 がスライドしていきます 71