var list = [ {name: "tsuyoshi", address: "kyoto", from: "kanagawa"}, {name: "ryoko", address: "kyoto", from: "osaka"} ];
このオブジェクトから
表の各オブジェクトの値であるtbodyの方を作成してみます。
function buildTable(){ //ここまでのコードは省略 //theadをtableに入れる table.appendChild(thead); //tbodyをtableに入れる table.appendChild(buildTbody()); return table; } //の部分だけ組み立てる function buildTbody(){ }
buildTable関数のreturn table;の前にbuildTbody関数を用意して、そこでtbodyの箇所を作成します。
//<tbody>の部分だけ組み立てる function buildTbody(){ var tbody = document.createElement("tbody"); //forの中で使用する変数はforの前で定義しておく var tr; var td; //listから各人のオブジェクトを取得する for (var i = 0; i < list.length; i++ ) { var personObj = list[i]; tr = document.createElement("tr"); //オブジェクト内にある各要素をtdで挟んでtrタグに入れる for ( key in personObj ) { td = document.createElement("td"); td.innerText = personObj[key]; tr.appendChild(td); } tbody.appendChild(tr); } return tbody; }
buildTbody関数内で、tbodyを作成した後、最初のforで配列の中にある各人の情報が入ったオブジェクト、次のforでオブジェクトの中に入っている各値を呼び出し、DOM操作でtdで囲って、
<tbody> <tr> <td>tsuyoshi</td> <td>kyoto</td> <td>kanagawa</td> </tr> <tr> <td>ryoko</td> <td>kyoto</td> <td>osaka</td> </tr> </tbody>
このようなHTMLタグのオブジェクトを作成して、buildTable関数内でtableのtheadの後に作成したtbodyのタグを挿入します。ここまでのコードを実行してみると、
最初に用意したlistオブジェクトの値を元に表ができました。試しに
var list = [ {name: "tsuyoshi", address: "kyoto", from: "kanagawa"}, {name: "ryoko", address: "kyoto", from: "osaka"}, {name: "taro", address: "tokyo", from: "hokkaido"} ];
新しい人のオブジェクトを追加して、コードを実行してみると、
新しく追加した人の情報も表示されます。これで人数がいくら増えても、追加に合わせて行を追加することができる様になりました。DOM操作でオブジェクトから表を組み立てて表示する1
DOM(Document Object Model)とはJavaScriptでHTMLのタグを取得したり、挿入したりでプログラミングで見た目を変えるために利用する仕組みです。document.querySelector("#〇〇");でタグからオブジェクトを取得するのもDOM操作です。今回は、
var list = [ {name: "tsuyoshi", address: "kyoto", from: "kanagawa"}, {name: "ryoko", address: "kyoto", from: "osaka"} ];
用意したオブジェクトをHTMLではなく、JavaScriptで
このような表を作ります。始めにこの表をHTMLで書く場合、
<table border="1px"> <thead> <tr> <th>名前</th> <th>住所</th> <th>出身</th> </tr> </thead> <tbody> <tr> <td>tsuyoshi</td> <td>kyoto</td> <td>kanagawa</td> </tr> <tr> <td>ryoko</td> <td>kyoto</td> <td>osaka</td> </tr> </tbody> </table>
このようなコードになります。それでは、このコードをJavaScriptで書いてみます。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>DOMでtable</title> <script> var list = [ {name: "tsuyoshi", address: "kyoto", from: "kanagawa"}, {name: "ryoko", address: "kyoto", from: "osaka"} ]; function buildTable(){ } </script> </head> <body> </body> </html>
始めに上記のようなコードを用意して、buildTable関数で表のHTMLを作ることにしましょう。
function buildTable(){ var table = document.createElement("table"); //外枠をつける table.border = "1px"; }
始めに、document.createElementで大元のtableタグを作成します。createElementの引数にタグ名を指定すると、指定した名前の開始タグを終了タグのオブジェクトが作成されます。
document.createElement("table");で<table></table>が作成されます。次にtable.border = "1px";で<table border="1px"></table>になります。この仕組みを応用して、中の枠も作成していきます。
最初にtheadで囲まれた箇所を作成していきます。
function buildTable(){ var table = document.createElement("table"); //外枠をつける table.border = "1px"; //<thead>を用意する var thead = document.createElement("thead"); //<tr>を用意する var tr = document.createElement("tr"); }
document.createElementで<thead>や<tr>といった必要なタグのオブジェクトを作成しておきます。この時点では、<table>、<thead>や<tr>はバラバラに存在しています。一旦この状態で置いといて、<tr>の中身を作成してみます。
function buildTable(){ //<table>と<thead>の箇所は一旦省略 var tr = document.createElement("tr"); //各項目を作る var th = document.createElement("th"); th.innerText = "名前"; tr.appendChild(th); //新たに<th>を作る th = document.createElement("th"); th.innerText = "住所"; tr.appendChild(th); //新たに<th>を作る th = document.createElement("th"); th.innerText = "出身"; tr.appendChild(th); }
<tr>タグの中に<th>を入れて、項目を表示する際、
th = document.createElement("th"); th.innerText = "名前";
で、<th>名前</th>を作った後、
tr.appendChild(th);
事前に用意したtrでappendChild(th)をすることで、
<tr></tr>のタグの間に作成した<th>名前</th>を入れるということになり、
<tr> <th>名前</th> </tr>
ということになります。残りの二つの要素も追加して、
<tr> <th>名前</th> <th>住所</th> <th>出身</th> </tr>
trのオブジェクトがこのような状態になったら、事前に用意した<table>や<thead>に同じような要領で、
<table border="1px"> <thead> <tr> <th>名前</th> <th>住所</th> <th>出身</th> </tr> </thead> </table>
このようになります。ここまでの状態をコードにまとめると、
function buildTable(){ var table = document.createElement("table"); //外枠をつける table.border = "1px"; var thead = document.createElement("thead"); var tr = document.createElement("tr"); //各項目を作る var th = document.createElement("th"); th.innerText = "名前"; tr.appendChild(th); //新たに<th>を作る th = document.createElement("th"); th.innerText = "住所"; tr.appendChild(th); //新たに<th>を作る th = document.createElement("th"); th.innerText = "出身"; tr.appendChild(th); //項目ができたら、theadに入れる thead.appendChild(tr); //theadをtableに入れる table.appendChild(thead); //作成した表のオブジェクトを返す return table; }
このように書きます。一度、この状態で表を表示させてみましょう。buildTable関数で作った表は現時点ではどこにも表示されていないことになっていて、これをdocument.querySelectorを利用して表示します。
HTMLで表を表示する箇所は<body>タグの中、すなわち、<body>表</body>と<body>タグの中に表のHTMLを挿入すれば良いわけで、bodyタグのオブジェクトを取得して、appendChildで表のHTMLを挿入すれば良いことになります。まずはbodyタグを取得してみます。
document.querySelector("body");とquerySelectorの中の引数で#無しでタグ名を指定すると、HTML内にあるbodyタグで一番初めに出てくるものを取得することになっており、bodyタグは1回しか使用できないため、この書き方で目的のbodyタグオブジェクトは取得できます。あとは、appendChildで
var body = document.querySelector("body"); body.appendChild(buildTable());
buildTable関数で作成した表のHTMLを挿入すれば良いです。ここまでのコードを書いてみると、
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>DOMでtable</title> <script> var list = [ {name: "tsuyoshi", address: "kyoto", from: "kanagawa"}, {name: "ryoko", address: "kyoto", from: "osaka"} ]; window.onload = function(){ var body = document.querySelector("body"); body.appendChild(buildTable()); }; function buildTable(){ var table = document.createElement("table"); //外枠をつける table.border = "1px"; var thead = document.createElement("thead"); var tr = document.createElement("tr"); //各項目を作る var th = document.createElement("th"); th.innerText = "名前"; tr.appendChild(th); //新たに<th>を作る th = document.createElement("th"); th.innerText = "住所"; tr.appendChild(th); //新たに<th>を作る th = document.createElement("th"); th.innerText = "出身"; tr.appendChild(th); //項目ができたら、theadに入れる thead.appendChild(tr); //theadをtableに入れる table.appendChild(thead); return table; } </script> </head> <body> </body> </html>
window.onloadイベントでbodyにtableを挿入する様に処理して、このコードを実行してみます。
HTMLの方でbodyタグ内に何も書いてない状態で、表の一部が表示されていることを確認しましょう。2014年12月20日土曜日
スタイルシートのルール
スタイルシートで指定する場合、いくつかのパターンがあります。たとえば、
<input type="text" id="form">
このようなタグがあった場合、id名の前にシャープをつけて、
#form{ width:40px; }
このように指定しますが、HTMLファイル内の<input type="text">のすべてに同じ装飾を施したい場合は、
input[type="text"]{ padding:5px; }
このようにタグとタイプを指定することでもデザインを当てることができます。pタグやbodyタグの一括の設定の場合も
body{ font-family:メイリオ; } p{ /** 文字間隔 **/ letter-spacing: 1em; }
idですが、たとえば同じHTMLファイル内の他のところでも#formのデザインを当てたくても、idは1つのファイルに1回のみしか使用出来ません。文字の色を赤にしたいといったスタイルを用意する場合は、
<input type="text" class="red">
.red{ color:red; }
このようにタグにclassで要素を追加し、スタイルシートでは、.クラス名で要素を追加することで.redは同じファイル内で何度も使用することが出来る様になります。2014年12月14日日曜日
お絵かきアプリにカラーパレットを追加しよう
HTMLで<input type="color">を書くことで、カラーパレットを追加することができるので、このカラーパレットをJavaScriptでつないで、お絵かきアプリの色変え機能として取り込んでみます。(ブラウザはChromeを推奨)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>draw</title> <style> #canvas { border: 1px solid #000000; } </style> <script> //コードは省略 </script> </head> <body> <canvas id="canvas" width="400px" height="300px"></canvas><br> <input id="pallet" type="color" value="#000000;"> </body> </html>
canvasの下にカラーパレットのinputタグを追加することで、
canvasの下にカラーパレットを呼び出せるボタンが追加されました。あとはこのパレットで選択した色を描写の際に反映させます。
<script> var canvas; var ctx; //パレット用の変数 var pallet; var drawFlag = false; window.onload = function(){ canvas = document.querySelector("#canvas"); ctx = canvas.getContext("2d"); //ここでパレットのオブジェクトを取得しておく pallet = document.querySelector("#pallet"); canvas.addEventListener("mousemove", function(event){ if (drawFlag === true) { var x = event.offsetX; var y = event.offsetY; //パレットで決めた色を点の描写直前で決めておく ctx.fillStyle = pallet.value; ctx.fillRect(x, y, 2, 2); } }); canvas.addEventListener("mousedown", function(event){ drawFlag = true; }); canvas.addEventListener("mouseup", function(event){ drawFlag = false; }); }; </script>
パレットの値は他のアプリでフォームの取得の時と同様でdocument.querySelectorでオブジェクト取得、変数.valueで値を取得という手順をとり、点の描写直前でfillStyleプロパティにカラーコードを入れます。
これでいろんな色でお絵かきできる様になりました。2014年12月13日土曜日
Canvas APIでお絵かきアプリを作ろう
CanvasAPIでマウスでお絵かきできるアプリを作ります。はじめにお絵かきをするパレットを用意します。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>お絵かきアプリ</title> <style> //canvasで作ったパレットに外枠を追加する #canvas { border: 1px solid #000000; } </style> <script> //ここにコードを書く </script> </head> <body> <canvas id="canvas" width="400px" height="300px"></canvas> </body> </html>
HTMLの記述でcanvasタグを入れておきます。この時、タグ内で横(width)と縦(heigth)を決めておかないと、お絵かきアプリが思った様に動作しないことがあります。
canvasが表示されたら、コードを書いていきます。
<script> var canvas; var ctx; window.onload = function(){ canvas = document.querySelector("#canvas"); ctx = canvas.getContext("2d"); //マウスが動いた時に実行されるイベント canvas.addEventListener("mousemove", function(event){ //現在のマウスの位置を取得する var x = event.offsetX; var y = event.offsetY; //マウスの位置に合わせて、一辺が2pxの四角を描写する ctx.fillRect(x, y, 2, 2); }); }; <script>
scriptタグで上記のコードを書いて実行してみると、
マウスが動く度に点が描写されますが、動きに合わせて常に点が描写されてしまいます。次にマウスの左ボタンをクリックした時だけ点が描写される様に修正してみます。
<script> var canvas; var ctx; //マウスの左ボタンをクリックしているかの判定用変数 var drawFlag = false; window.onload = function(){ canvas = document.querySelector("#canvas"); ctx = canvas.getContext("2d"); canvas.addEventListener("mousemove", function(event){ //クリックしている時だけ点を描写する様にする if (drawFlag === true) { var x = event.offsetX; var y = event.offsetY; ctx.fillRect(x, y, 2, 2); } }); //マウスの左ボタンをクリックした時の処理 canvas.addEventListener("mousedown", function(event){ drawFlag = true; }); //マウスの左ボタンのクリックを止めた時の処理 canvas.addEventListener("mouseup", function(event){ drawFlag = false; }); }; </script>
マウスの左ボタンをクリックしているかを判定するフラグの変数を用意して、mousemoveイベントの点の描写の直前にif文で判定を追加した後、マウスの左ボタンをクリックした時のイベントであるmousedownとクリックを止めた時のイベントであるmouseupをaddEventListenerで追加して、mousedownイベントの時はdrawFlagをtrueにして押している状態にし、mousemoveイベントでの点の描写を許可し、mouseupイベントの時にdrawFlagをfalseにして、mousemoveイベントでの点の描写を禁止することによって、マウスでお絵かきできる様にします。この状態で実行してみると、
マウスの左ボタンのクリックとマウスの動きに合わせてお絵かきできる様になっています。2014年12月8日月曜日
JavaScriptの配列とオブジェクト、HTMLのフォームでクイズを作ろう2
前回はJavaScriptの配列とオブジェクト、HTMLのフォームを使ってクイズを作りました。しかし、前回のコードでは回答した時に記録をとっていないので、何度か回答していると同じ問題が出題されるということがあります。今回は一度回答した問題は出題しないという処理を追加してみます。始めに出題番号を入れる変数と回答を記録する変数を用意します。変数の型は配列にしておきます。
var quizzes = [/** 出題内容は省略 **/]; var quiz; //出題番号を入れておく var questionNumber; //回答を記録しておく変数 var answered = []; window.onload = function(){ init(); }; function init(){ var r = Math.floor(Math.random() * quizzes.length); quiz = quizzes[r]; //問題用のフォームに表示する var questionForm = document.querySelector("#question"); questionForm.value = quiz.q; } function doAnswer(){ //回答時の処理は省略 } function right(){ //正解した時の処理は省略 } function wrong(){ //不正解の時の処理は省略 }
出題番号の記録と回答の記録用の配列を用意したら、始めにinit関数を修正します。
function init(){ var r = Math.floor(Math.random() * quizzes.length); quiz = quizzes[r]; //出題番号を入れておく questionNumber = r; //問題用のフォームに表示する var questionForm = document.querySelector("#question"); questionForm.value = quiz.q; }
次に正解時に回答用の配列に答えた問題番号を入れておきます。
function right(){ alert("正解です"); //答えた問題の出題番号を記録しておく answered.push(questionNumber); init(); }
出題番号を回答用の配列に入れる時は、配列の変数.push(値)を利用します。これで回答した問題の番号の記録はできました。後は出題の直前ですでに回答した問題か調べて出題します。init関数を修正します。
function init(){ //init関数の中だけでr変数を使用する var r; //既に出題しているかを調べる //alreadyがfalseの場合は再度出題番号を取得する var already = true; do{ r = Math.floor(Math.random() * quizzes.length); for ( var i = 0; i < answered.length; i++ ) { //取得した出題番号がすでに回答済みの場合はfalseを入れる if ( answered[i] == r ) { already = false; } } }while(already == false); quiz = quizzes[r]; questionNumber = r; //問題用のフォームに表示する var questionForm = document.querySelector("#question"); questionForm.value = quiz.q; }
do-while文とif文を利用して、出題番号を取得した後にすでに回答済みか調べて、回答していない問題の出題番号を取得します。これで同じ問題が出題されるということはなくなります。しかしこの状態では、すべての問題を回答後にinit関数でまだ回答していない問題の出題番号を取得し続けるという処理が残ってしまうため、right関数の方に全問回答の処理を追加しておきます。
function right(){ alert("正解です"); //答えた問題の出題番号を記録しておく answered.push(questionNumber); //全問回答した場合 if (answered.length == quizzes.length) { //クイズを終了する処理を追加 //問題が残っている場合は出題する } else { init(); } }
right関数内の次の出題を行う処理のところにif文を追加して、全問正解の場合はクイズを終了するという処理を追加しておきます。これで出題番号を取得し続ける不具合は解決します。JavaScriptの配列とオブジェクト、HTMLのフォームでクイズを作ろう1
JavaScriptでクイズを作るとき、HTMLのフォームとJavaScriptの配列とオブジェクトを利用します。始めにクイズの配列を用意します。
<!DOCTYPE html> <html> <head> <title>クイズ</title> <script> //出題と答えをセットで入れる配列 var quizzes = []; </script> </head> </html>
配列を用意したら、この配列に出題と答えのセットのオブジェクトを入れます。
var quizzes = [ {q : "日本の首都は?", a : "東京"}, {q : "アメリカの首都は?", a : "ワシントン"}, {q : "イギリスの首都は?", a : "ロンドン"} ];
これで、quizzes[1]の様に配列内のインデックスの指定でクイズのオブジェクトを取得できる様になりました。ちなみにquizzes[1]でアメリカの首都の問題が取得できます。次に出題表示用と回答用のフォームを用意します。
<!DOCTYPE html> <html> <head> <title>クイズ</title> <script> //出題と答えをセットで入れる配列 var quizzes = [ {q : "日本の首都は?", a : "東京"}, {q : "アメリカの首都は?", a : "ワシントン"}, {q : "イギリスの首都は?", a : "ロンドン"} ]; </script> </head> <body> 問題:<input type="text" id="question" value=""><br> <input type="text" id="answer" value=""> <input type="button" value="答える"> </body> </html>
このコードを実行してみると、
出題用と回答用のフォームが表示されます。それでははじめに問題フォームに用意した出題オブジェクトを表示してみます。
始めに出題用のinit関数を用意します。
//出題と答えをセットで入れる配列 var quizzes = [ {q : "日本の首都は?", a : "東京"}, {q : "アメリカの首都は?", a : "ワシントン"}, {q : "イギリスの首都は?", a : "ロンドン"} ]; //出題前に取得するオブジェクトを入れておく変数 var quiz; function init(){ var r = Math.floor(Math.random() * quizzes.length); quiz = quizzes[r]; //問題用のフォームに表示する var questionForm = document.querySelector("#question"); questionForm.value = quiz.q; }
init関数で行っていることは、quizzes配列からランダムに出題用のオブジェクトを取得しておいて、その後にHTMLの問題のフォームの方に問題文を表示させています。init関数が用意できたら、ファイルを表示し終わった直後に実行されるwindow.onloadで実行してみましょう。
//出題と答えをセットで入れる配列 var quizzes = [ {q : "日本の首都は?", a : "東京"}, {q : "アメリカの首都は?", a : "ワシントン"}, {q : "イギリスの首都は?", a : "ロンドン"} ]; //出題前に取得するオブジェクトを入れておく変数 var quiz; window.onload = function(){ init(); }; function init(){ var r = Math.floor(Math.random() * quizzes.length); quiz = quizzes[r]; //問題用のフォームに表示する var questionForm = document.querySelector("#question"); questionForm.value = quiz.q; }
window.onload内でinit関数を実行することで、
問題文のフォームにクイズが表示されました。次は回答の処理を追加してみます。回答の処理は回答用のフォームに文字を入力した後、答えるボタンを押して入力した内容が正しいか調べるという流れで、はじめに回答するという処理を追加する為に、doAnswerという関数を追加して、処理を書いていくことにします。
var quizzes = [/** 出題用のオブジェクトは省略 **/]; var quiz; window.onload = function(){ init(); }; function init(){ var r = Math.floor(Math.random() * quizzes.length); quiz = quizzes[r]; //問題用のフォームに表示する var questionForm = document.querySelector("#question"); questionForm.value = quiz.q; } function doAnswer(){ //回答用のフォームに入力した値を取得 var answerForm = document.querySelector("#answer"); var answer = answerForm.value; //回答用フォームで入力した内容を削除する answerForm.value = ""; //入力した内容が正しいか調べる if (answer == quiz.a) { //入力した内容が正解の時 } else { //入力した内容が不正解の時 } }
doAnswer関数では、回答用のフォームに入力した値を取得した後、if文で入力した内容が正解であるかを調べています。正解、不正解の時の処理は一旦置いといて、答えるボタンを押したらdoAnswer関数が実行するようにします。
問題:<input type="text" id="question" value=""><br> <input type="text" id="answer" value=""> <input type="button" value="答える" onclick="doAnswer();">
ボタンを押したら実行という処理を追加する時は、ボタンのタグにonclick="関数名"を追加すれば良いです。これで回答するという処理を追加することができました。後は正解、不正解の時の処理を追加して、クイズを完成させていきます。正解、不正解共にポップアップで表示して、次の問題を出題するという処理を追加してみます。
var quizzes = [/** 出題用のオブジェクトは省略 **/]; var quiz; window.onload = function(){ init(); }; function init(){ var r = Math.floor(Math.random() * quizzes.length); quiz = quizzes[r]; //問題用のフォームに表示する var questionForm = document.querySelector("#question"); questionForm.value = quiz.q; } function doAnswer(){ //回答用のフォームに入力した値を取得 var answerForm = document.querySelector("#answer"); var answer = answerForm.value; //回答用フォームで入力した内容を削除する answerForm.value = ""; //入力した内容が正しいか調べる if (answer == quiz.a) { //入力した内容が正解の時 right(); } else { //入力した内容が不正解の時 wrong(); } } //正解の時に実行する関数 function right(){ alert("正解です"); init(); } //不正解の時に実行する関数 function wrong(){ alert("不正解です"); }
正解用と不正解用の関数を追加して、正解用では、正解の表示と次の問題の出題(init)、不正解用では、不正解の表示のみを行うようにし、doAnswer関数の回答判定に追加しています。ここまでできたら、このファイルを実行してみましょう。
出題と回答が実装され、クイズアプリができました。登録: 投稿 (Atom)