HTMLとJavaScriptの連携ができるとどうなる?
ボタンを押したときにダイアログを出す。
通信して取得したデータをWebページに表示する。
など動きのあるページが作れるようになる!
htmlだけではできない動きがJavaScriptによってできるようになるのでできることが広がる。
前提
JavaScriptの基礎を理解していること。
htmlからJavaScriptの読み込みができる。 (以下)
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<script type="text/javascript" src='./main.js'></script>
<title>Document</title>
</head>
<body>
<p>Hello World</p>
</body>
</html>
本記事ではこれをベースに進めていく。
ボタンを押したらダイアログを表示する
3ステップで作成していく。
htmlでボタンを表示する
まずはボタンを作る
<body>
<button>ここを押してね!</button>
</body>
buttonタグで囲むだけ。
これを書いたらブラウザでボタンが表示されていることを確認。
押してもなにもおきない。
JavaScript側に関数を用意
const alertHelloWorld = () => {
alert("HelloWorld");
}
alert
は文字列をダイアログで表示するための関数。
ボタンを押したときに関数を呼び出す。
ボタンタグにonclick
を追加する。
<body>
<button onclick="alertHelloWorld()">ここを押してね!</button>
</body>
これでブラウザで確認できる。
関数名だけではなく()
をつけることに注意。
JavaScriptから文字をWebページに表示させる
ボタン押す前 | ボタン押した後 |
---|---|
文字が変わる |
html側の用意
最初に表示する文字をhtmlに仕込んでおく。
<body>
<div id="canvas">ここに文字をいれる</div>
<button onclick="drawCanvas()">ここを押してね!</button>
</body>
ポイントは<div id="canvas">
。
div要素にidをつける。
idをつけることでJavaScript側から要素を取得することが可能になる。
id名はとくに決まりはないが、ここでは何かしらを描くところって意味でcanvas
という名前にした。
文字を変更する
JavaScript側でやることは
- idが"canvas"の要素を取得し、
- そこに新しい文字列をつっこむ
の2つ。
それは以下のように書ける
const drawCanvas = () => {
const canvas = document.getElementById("canvas");
canvas.innerHTML = "Hello JavaScript!";
}
ポイント
IDを用いた要素の検索。
const 要素 = document.getElementById("ID名");
要素の中身の変更
要素.innerHTML = "新しい中身";
これでブラウザでボタンを押したときに表示が変わることが確認できる。
最初に表示する文字もJavaScriptから設定する。
なるべくJavaScript側に書きたいので最初に表示する文字もJavaScript側で書きたい。
読み込み時に設定するためにmain.jsをで以下のように書く。
// 初期化用の関数を用意
const initialize = () => {
const canvas = document.getElementById("canvas");
canvas.innerHTML = "ここに文字をいれる";
}
// 読み込み時に呼び出す。
initialize();
html側には文字を入れないでおく
<body>
<div id="canvas"></div>
<button onclick="drawCanvas()">ここを押してね!</button>
</body>
そしてコンソールには以下のようなエラーが表示される。
uncaught TypeError: Cannot set property 'innerHTML' of null at initialize
initializeの該当部分は以下
const canvas = document.getElementById("canvas");
canvas.innerHTML = "ここに文字をいれる";
「nullにはinnerHTMLっていうプロパティーないよ」
=> canvasはnullである (何にも入ってないって意味)
=> document.getElementById("canvas")が失敗している。
と推測できる。
で、じゃあなぜ失敗するかというと、jsの読み込みのタイミングの問題。
現状以下のような流れになっている。
bodyの中身を描画する前にjsの読み込みが走っているのでまだ「canvas」がないってこと。
そこでjsの読み込みタイミングを遅くする。
そのやり方の一つが以下。
// before
<script type="text/javascript" src='./main.js'></script>
// after
<script type="text/javascript" src='./main.js' defer></script>
main.jsを読み込むときにdeferをつける。
するとちゃんと初期化されるようになる。
JavaScriptから色を変える
idから取得した要素は文字の内容を変えるだけでなく他にもいろいろ変えられる。
そこでまずは色を変えてみる。
const drawCanvas = () => {
const canvas = document.getElementById("canvas");
canvas.innerHTML = "Hello JavaScript!";
canvas.style.color = 'red'; // <- ここ
}
色の設定は決められた文字ではなくカラーコードでもOK
const drawCanvas = () => {
const canvas = document.getElementById("canvas");
canvas.innerHTML = "Hello JavaScript!";
canvas.style.color = '#00FF00';
}
他にもいろいろ変えられるのでcssで変えられるものを試してみるとよい。
const drawCanvas = () => {
const canvas = document.getElementById("canvas");
canvas.innerHTML = "Hello JavaScript!";
canvas.style.color = '#00FF00';
canvas.style.backgroundColor = 'red'; // 背景色変更
canvas.style.padding = '10px'; // 領域を広くする
}
応用するとこんなこともできる
ここはやらなくて大丈夫。
非同期とかできるようになるとこんな感じのアニメーションとかも作れるようになる。
const sleep = (msec) => new Promise(resolve => setTimeout(resolve, msec));
const drawTextAsync = async () => {
const canvas = document.getElementById("canvas");
canvas.style.backgroundColor = 'white';
canvas.style.color = 'black'
canvas.innerHTML = " ";
await sleep(100);
const word = "Hello JavaScript!";
for (var i = 0; i < word.length; i++) {
const content = word.substr(0, i+1);
canvas.innerHTML = content;
await sleep(100);
}
canvas.style.backgroundColor = 'red';
canvas.style.color = 'white'
}