色々な書き方
今回は、以下のHTMLを
という方法で作る方法を学びます。
<div id="img_unit">
<div class="photo">
<img src="img/img01.jpg">
<div class="inner">
<p>コメント1<span>name01</span></p>
</div>
</div>
<div class="photo">
<img src="img/img02.jpg">
<div class="inner">
<p>コメント2<span>name02</span></p>
</div>
</div>
</div>
なお、それぞれのhtmlファイルを index.html
と言う名前だと仮定し以下のようなファイルパス関係だとします。
.
├── index.html
└── img
├── img01.jpg
├── img02.jpg
└── img03.jpg
ちなみに、以下の css
を読み込んでおくと綺麗に表示されます。
body {
margin: 0;
padding: 0;
background-color: rgba(26, 55, 229, 0.06);
}
.container { /*<div class="container">で上記のhtmlを囲むとより綺麗に表示されます。*/
max-width: 600px;
margin: 0 auto;
box-shadow: 0px 0px 3px rgba(0, 0, 0, .3);
}
img {
width: 100%;
margin 0;
vertical-align: top;
}
.photo {
position: relative; /*親要素に relative とすることで下で absolute が photo に対して行われる。*/
}
.photo .inner {
position: absolute;
bottom: 0;
background-color: rgba(0, 0, 0, .5);
font-size: 10px;
color: #fff;
margin: 0;
width: 100%;
}
.inner p {
padding: 20px;
}
.inner span {
margin-left: 10px;
}
json から読み込む
Json(JavaScript Object Notation)ファイルにデータを用意しておいて、それらを随時読み込んで表示する方式。
以下のどちらを利用するかは自由。
- htmlを直接
innerHTML
プロパティで挿入する。 createElement
やappendChild
を使って要素をオブジェクトとして扱う。
<div id="img_unit">
</div>
<script>
var images = [
{
"path": "img/img01.jpg",
"name": "name01",
"caption": "コメント1"
},
{
"path": "img/img02.jpg",
"name": "name02",
"caption": "コメント2"
},
{
"path": "img/img03.jpg",
"name": "name03",
"caption": "コメント3"
}
];
var img;
var caption;
var div;
for (var i=0; i<images.length; i++){
img = document.createElement('img'); // <img>タグが作られる。
img.setAttribute('src', images[i].path); // src属性を追加し、属性値を設定。
caption = document.createElement('div'); // <div>タグが作られる。
caption.className = 'inner'; // class属性を追加し、属性値を設定。
caption.innerHTML = '<p>' + images[i].caption + '<span>' + images[i].name + '</span></p>'; // divタグの中に<p>...</p>という要素を追加。
div = document.createElement('div');
div.className = 'photo';
div.appendChild(img); // divの内部にimgを追加する。
div.appendChild(caption); // divの内部にcaptionを追加する。
document.getElementById('img_unit').appendChild(div); //"id=img_unit"のタグの内部にdivを追加する。
}
</script>
直書きでAjax通信を使う
プログラムの中にjsonデータを保持しているのは賢いやり方ではない。
というか、API(Application Programing Interface)を使って外部と通信しながらデータを処理することがほとんどであり、その時に使えるのがAjax通信。
なお、ここでは、"https://h2o-space.com/htmlbook/images.php" というサーバーと通信を行なっているが、これはjsonのセキュリティの問題のため。
file
がCross origin requestsでサポートされているプロトコルに含まれていない(セキュリティ上危ないから)ので、講師の方が用意してくださっている。
また、ajax通信は以下のようにいくつかのステップに分かれており、それぞれに状態が割り当てられているので、通信が終わったことを確認してから次の処理を行うことができる。
値 | 定数 | 状態 |
---|---|---|
0 | UNSENT | インスタンスができた |
1 | OPENED | openメソッドを利用した |
2 | HEADERS_RECEIVED | ヘッダーが受信できた |
3 | LOADING | データを受信中である |
4 | DONE | 通信が終了した |
<div id="img_unit">
</div>
<script>
var ajax = new XMLHttpRequest(); //ajax通信を行うためのオブジェクト。XMLはデータ形式の一つだが、ここではJsonでデータのやり取りを行う。
// alert(ajax.readyState); // 0
ajax.open('GET', 'https://h2o-space.com/htmlbook/images.php'); // ajax通信を行う相手先のアドレス(講師の方が用意してくださっている。)
// alert(ajax.readyState); // 1 (openを行なった後)
ajax.responseType = 'json'; // データの形式を指定
ajax.send(null); // ファイルを呼び出す。
ajax.onreadystatechange = function(){
if (ajax.readyState === XMLHttpRequest.DONE && ajax.status === 200){
for (var i=0; i<this.response.length; i++){
var data = this.response[i];
img = document.createElement('img');
img.setAttribute('src', data.path);
caption = document.createElement('div');
caption.className = 'inner';
caption.innerHTML = '<p>' + data.caption + '<span>' + data.name + '</span></p>';
div = document.createElement('div');
div.className = 'photo';
div.appendChild(img);
div.appendChild(caption);
document.getElementById('img_unit').appendChild(div);
}
}
};
</script>
jquery
でAjax通信を使う
jqueryの公式サイトから、jqueryをダウンロードし、js/jquery.min.js
に保存してください。
<div id="img_unit">
</div>
<script src="js/jquery.min.js"></script>
<script>
$.getJSON('https://h2o-space.com/htmlbook/images.php', function(data) { // コールバック(処理が終わった時に自動的に呼び出されるファイルのこと。)
for (var i=0; i<data.length; i++){
$('<div class="photo"></div>')
.append('<img src="' + data[i].path + '">') // 自分自身「に」追加する。
.append('<div class="inner"<p>' + data[i].caption + '<span>' + data[i].name + '</span></p></div>')
.appendTo('#img_unit'); // 自分自身「を」追加する。
}
});
/* サンプル(htmlを生成する。)
$(#img_unit).html('ここに、画像リストが表示されます。');
$(#img_unit).css('margin-top', '100px');
*/
</script>
vue.js
でAjax通信を使う
jquery だとhtmlを生成する際に要素をそのままscript内に書いており、少しわかりにくかったです。そこで、vue.jsというライブラリがよく使われる。
なお、vue.jsは公式サイトにてcdnで配布されています。
vue,jsは以下の形が基本で、プレースホルダーを書き換える、といった操作を行います。
<div id="vue_unit">
{{ message }}
</div>
<script>
var app = new Vue({
el: '#vue_unit',
data: {
message: 'vue.jsで書き換えました。'
}
});
</script>
今までのサンプルに適用すると、以下のようになります。なお、プレースホルダーを属性値の中に書くことができないので、別の書き方をしています。
<div id="img_unit">
<div class="photo" v-for="Photo in Photos"> <!-- vue.js の for構文を使っている。 -->
<img :src="Photo.path"> <!-- vue.js によって書き換えられる対象となる。 -->
<div class="inner"><p>{{ Photo.caption }}<span>{{ Photo.name }}</span></p></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="js/jquery.min.js"></script>
<script>
var app = new Vue({
el: '#img_unit',
data: {
Photos: []
},
created: function() { // vueのオブジェクトが作られる時のメソッド
var self = this; // ここでのスコープのthisを保存しておく。
$.getJSON('https://h2o-space.com/htmlbook/images.php', function(data) {
self.Photos = data
});
}
});
</script>
最後に
これで、講義で習った事は終了しました:)