入門編『構文』【魔導書視点】
「そうだな、簡単なjavascriptを組んでみるか?」
「えっ、うん、やる」
即答だった。エイダのやる気満々の熱量に、少したじろんでしまった。まったく、若いって最高だぜ!!
「ちょっと待ってて」
しかし、また安請け合いをしてしまった。困った。
エイダは魔導書のページしか見えないので、今私が使っているエディターは使えない。ブラウザの一つのページに入力用のテキストエリアと、結果を表示するHTMLエリアを設けないといけない。ちょっとだけ面倒だ。色々と思案し、全体の方針が決まった。入力用にTEXTAREAと、表示用にIFRAMEを使うのが妥当かな?早速、作業に取り掛かる。
<script>
</script>
ここでふと手が止まる。HTMLタグでTEXTAREAとIFRAMEを作成してもいいけど、それぞれにIDを指定してjavascriptのdocument.getElementByIdで、結局取ってこないといけない。うむ、面倒だ。
作業としては全然大変ではないのだが、プログラマはとにかく面倒臭がり屋だ。後で楽をする為、大変な苦労を課してプログラムを組み立てる。簡単な抜け道が存在しても、敢えて茨の道を進も時もある。自分の美学を曲げる事なんて以ての外だ。そして要らぬ時間を浪費し、ポリシーを貫いて書いたコードは、後々全く使われず肥やしになる事が多い。全く何の為に、苦労して書いたのやら。面倒臭がりで、楽をする為に(あらぬ方向に)努力を惜しまない。兎にも角にも、矛盾を抱えた人種だ。
全部、javascriptで書いちゃおうっと。
また自分の悪い癖が出てしまった。全然直そうとは思ってないが、時々自分でも呆れる。まぁこっちの方が、面白そうだし。さてと、document.createElementで作りますか。
<script>
var frame=document.createElement(“iframe”);
var textarea=document.createElement(“textarea”);
</script>
これだけでは要素を作っただけでなので、HTMLのボディにくっつけないといけない。
<script>
var frame=document.createElement(“iframe”);
var textarea=document.createElement(“textarea”);
body.appendChild(frame);
body.appendChild(textarea);
</script>
だったかな?保存と更新をしてみたが、何も表示されなかった。あれ?エラーコンソールを見ると。
ReferenceError: Can't find variable: body
bodyと言う変数が見つからないと怒ってらっしゃる。う〜ん、bodyではなく、document.bodyだったかな?
<script>
var frame=document.createElement(“iframe”);
var textarea=document.createElement(“textarea”);
document.body.appendChild(frame);
document.body.appendChild(textarea);
</script>
またエラーが出た。
TypeError: null is not an object (evaluating 'document.body.appendChild')
今度はdocument.bodyの変数はあったみたいだが、appendChildの関数を実行しようとした時、document.bodyがnullだとおっしゃられている。なぜだ?
しばらく考え、書いているスクリプトがヘッダー内の為、ボディが作られる前に実行されることを思い出した。
詳しく説明しよう。javascriptは4箇所に記入できる場所がある:HEAD内、BODY内、HREFタグ内、そして外部ファイル。今まで使っていたのはHEAD内の記入場所だったのだ。
<script>
//スクリプトはここに書く
</script>
と書くと、これは実はヘッダーにスクリプトを記入している事になる。構造的にはこんな感じだ。
<html>
<head>
<script>
//スクリプトはここに書く
</script>
</head>
<body>
</body>
</html>
そしてヘッダー(<HEAD>タグで囲まれた領域)は、ボディ(<BODY>タグで囲まれた領域)より先にブラウザに読み込まれ処理される。要するにdocument.bodyを参照しようにも、まだボディは作られていないのでnullなのだ。
<body>
<script>
//スクリプトはここに書く
</script>
</body>
対応策としては、bodyタグの中にscriptタグを置けばいいのだが、なんか負けた気分だ。ここはゴリ押しで行こう。
<script>
window.onload=function(){
var frame=document.createElement("iframe");
var textarea=document.createElement("textarea");
document.body.appendChild(frame);
document.body.appendChild(textarea);
}
</script>
HTMLのヘッダーとボディの読み込み《ロード》が完了したら、function(){}で囲われた関数のコードが実行される様に変更した。画面を確認すると無事にiframeとtextareaが、大きさが違うが表示されていた。
うーん、できたら上下に綺麗に二等分したいな。それにはHTMLのボディの縦と横のサイズを知らないと。横幅や縦幅の単語を含むプロパティー名だと思うんだけど。console.log('%O')を使って探してみよう。
<script>
window.onload=function(){
console.log("%O",document.body);
var frame=document.createElement("iframe");
var textarea=document.createElement("textarea");
document.body.appendChild(frame);
document.body.appendChild(textarea);
}
</script>
コンソールでそれらしき名前を探すと、clientWidthとclientHeightが画面サイズに近い値を持っていた。では早速IFRAMEとTEXTAREAのサイズを設定しよう。これは普通にstyleプロパティのwidthとheightが使えるはず。もちろん縦幅の値は2で割る。ついでに<BR>タグを真ん中に配置しておこう。
<script>
window.onload=function(){
var width=document.body.clientWidth;
var height=document.body.clientHeight;
var frame=document.createElement("iframe");
var textarea=document.createElement("textarea");
frame.style.width=width;
frame.style.height=height/2;
textarea.style.width=width;
textarea.style.height=height/2;
document.body.appendChild(frame);
document.body.appendChild(document.createElement("br"));
document.body.appendChild(textarea);
}
</script>
おぉ、ちゃんと二分割で表示されている。そしてテキストエリアも入力可能だ。余白がある為、IFRAMEとTEXTAREA両方ともちょっとはみ出ているが、ボディのpaddingやmarginの値を0にすれば大丈夫なはずだ。それよりも、TEXTAREAの内容をIFRAMEに書き込む機能を追加しないと。TEXTAREAをダブルクリックしたら(ondblclick)、テキストエリアに書かれた内容をtextarea.valueを使い、IFRAMEのdocumentにopen+write+closeで書き込むようにしよう。一応念の為、textarea.valueに値が入っているかログに出力する。
<script>
window.onload=function(){
var width=document.body.clientWidth;
var height=document.body.clientHeight;
var frame=document.createElement("iframe");
var textarea=document.createElement("textarea");
frame.style.width=width;
frame.style.height=height/2;
textarea.style.width=width;
textarea.style.height=height/2;
document.body.appendChild(frame);
document.body.appendChild(document.createElement("br"));
document.body.appendChild(textarea);
document.body.style.padding=0;
document.body.style.margin=0;
textarea.ondblclick=function(){
var doc=frame.document;
doc.open();
console.log(textarea.value);
doc.write(textarea.value);
doc.close();
};
}
</script>
よし、これでどうだ?保存して更新。テキストエリアを文字を書いてダブルクリックしてみると、また怒られた。
TypeError: undefined is not an object (evaluating 'doc.open')
openの関数を実行する時、docが未定義だと注意された。frame.documentはないのかな?またまたconsole.log('%O')を使って探してみよう。一応テキストエリアに書いた文字はログに出力されたので、textarea.valueは問題なさそうだ。marginとpaddingを0pxにしたおかげで、余白も同時に解決した。
<script>
window.onload=function(){
var width=document.body.clientWidth;
var height=document.body.clientHeight;
var frame=document.createElement("iframe");
var textarea=document.createElement("textarea");
frame.style.width=width;
frame.style.height=height/2;
textarea.style.width=width;
textarea.style.height=height/2;
document.body.appendChild(frame);
document.body.appendChild(document.createElement("br"));
document.body.appendChild(textarea);
document.body.style.padding=0;
document.body.style.margin=0;
console.log('%O',frame);
textarea.ondblclick=function(){
var doc=frame.document;
doc.open();
doc.write(textarea.value);
doc.close();
};
}
</script>
コンソールでログを軽く目を通し、怪しいプロパティ「contentWindow」に目が止まった。中身が空っぽいdocumentを含むので多分これだろう。
<script>
window.onload=function(){
var width=document.body.clientWidth;
var height=document.body.clientHeight;
var frame=document.createElement("iframe");
var textarea=document.createElement("textarea");
frame.style.width=width;
frame.style.height=height/2;
textarea.style.width=width;
textarea.style.height=height/2;
document.body.appendChild(frame);
document.body.appendChild(document.createElement("br"));
document.body.appendChild(textarea);
textarea.ondblclick=function(){
var doc=frame.contentWindow.document;
doc.open();
doc.write(textarea.value);
doc.close();
};
}
</script>
やっと出来た。早速、保存して更新。テキストエリアに「こんにちは」と書いてダブルクリックすると、IFRAMEにも「こんにちは」が表示された。普通のテキストの表示は上手くいった。さて仕上げに、javascriptもちゃんと動くか動作チェックしよう。
<SCRIPT>
alert("こんにちは");
</SCRIPT>
テキストエリアに入力しダブルクリックすると、「こんにちは」と警告文が表示された。javascriptも問題なさそうだ。
「下の入力領域エリアに術式スクリプトを書くと、上の出力領域エリアに表示するようにした。それでは始めよう」
こうして授業に使われる即席ツールは作られた。
登場人物
エイダ・ラブレス
冒険者に憧れている9歳の普通の女の子。
かなり母親に基礎を叩き込まれた模様。
喋る魔導書
エイダが森の奥で出会った喋る魔導書。
前世で観ていたアニメが少し偏っているような?
作者より
プログラマによりますが、結構行き当たりばったりに書いている人もいます。作者もこんな感じに、結構いい加減に組んでいます。ちょい書き(+テスト)の利点はエラー箇所が特定しやすい事でしょうか?何十行も書いてからテストするとエラーが重なり合い、発見しにくい場合があります。もう一つの利点は、ちゃんと動くのを確認できると、やる気を維持できる事が挙げられると思います。エラーが続きまくると、本当に心が折れます。
コードのコピペが多いので、簡単に5000文字を超えてしまってる。う〜ん、楽だ。
新しく追加された行を太文字や赤文字にして見やすく出来たらいいのですが、その機能は小説家になろうでは使えないみたいです。残念。
昨日の初めて評価もらえました。何らかの反応があると嬉しいですね。評価、ありがとうございます。
参考にしたページ
JavaScript4箇所の記入場所
http://www.pori2.net/js/kihon/2.html
%Oで出力する
https://qiita.com/nakajmg/items/9c6ad7e1e01e1204d430
JavaScript インラインフレーム(iframe)関連
http://wiki.bit-hive.com/tomizoo/pg/JavaScript%20%A5%A4%A5%F3%A5%E9%A5%A4%A5%F3%A5%D5%A5%EC%A1%BC%A5%E0%28iframe%29%B4%D8%CF%A2