#はじめに
ありとあらゆる所で使用されている超有名なJavaScriptライブラリといえば jQuery ですが、ちょっとした処理を行いたいがために使っているようであれば無駄な気もします。
最近のJavaScriptはjQueryなしでも割といろんな処理を行うことができます。
というのも、jQueryの動作を模倣してみようとゼロから書いた拙作のライブラリ queries.js を通してどのような処理を行っているのか理解が深まったからです。
宣伝になってしまいますが、queries.js へのリンクを貼っておきます。
jQueryライクなJavaScriptライブラリ queries.js
ちなみに、処理に関しては Internet Explorer 11 未満は考慮していません。
ここに書かれているコードのほとんどは意図的に関数化していません。これらのコードを元に自由に組んで自分で使いやすい関数にしていく方がいいと思うからです。
2017/04/07 追記: .index()
, .has()
を追加しました!
2017/03/28 追記: $.ajax()
を追加しました!
2017/03/21 追記: $.inArray()
, $.proxy()
, .siblings()
, .nextAll()
, prevAll()
を追加しました!
2017/03/17 追記: .closest()
, .width()
等を追加しました!
2017/03/16 追記:他のメソッドも追加しました!
#便利メソッド系
$.each()
や $.grep()
といったメソッドの代替となる記述です。
よく使いそうなものだけ取り上げています。
##$.each()
$.each()
は、配列やオブジェクトを簡単にループ処理できるメソッドです。
以下のような配列とオブジェクトがあったとします。
// 配列
var decoRations = ['諸星きらり', '城ヶ崎莉嘉', '赤城みりあ'];
// 配列っぽいオブジェクト
var candyIsland = {0: '双葉杏', 1: '三村かな子', 2: '緒方智絵里', length: 3};
// オブジェクト
var kbyd = {kawaii: '輿水幸子', yakyu: '姫川友紀', dosue: '小早川紗枝'};
これをループさせます。
/* 配列 */
$.each(decoRations, function (i, value) {
console.log(i + ': ' + value);
});
// "0: 諸星きらり"
// "1: 城ヶ崎莉嘉"
// "2: 赤城みりあ"
/* 配列っぽいオブジェクト */
$.each(candyIsland, function (i, value) {
console.log(i + ': ' + value);
});
// "0: 双葉杏"
// "1: 三村かな子"
// "2: 緒方智絵里"
/* オブジェクト */
$.each(kbyd, function (key, value) {
console.log(key + ': ' + value);
});
// "kawaii: 輿水幸子"
// "yakyu: 姫川友紀"
// "dosue: 小早川紗枝"
/* 配列 */
// Array.prototype.forEach
decoRations.forEach(function (value, i) {
console.log(i + ': ' + value);
});
// "0: 諸星きらり"
// "1: 城ヶ崎莉嘉"
// "2: 赤城みりあ"
/* 配列っぽいオブジェクト */
var forEach = Array.prototype.forEach;
forEach.call(candyIsland, function (value, i) {
console.log(i + ': ' + value);
});
// "0: 双葉杏"
// "1: 三村かな子"
// "2: 緒方智絵里"
/* オブジェクト */
// for...in 文
for (var key in kbyd) {
console.log(key + ': ' + kbyd[key]);
}
// "kawaii: 輿水幸子"
// "yakyu: 姫川友紀"
// "dosue: 小早川紗枝"
// Object.keys() を使った方法
Object.keys(kbyd).forEach(function (key) {
console.log(key + ': ' + kbyd[key]);
});
// "kawaii: 輿水幸子"
// "yakyu: 姫川友紀"
// "dosue: 小早川紗枝"
配列の場合は、Array.prototype.forEach
を使った方法、配列っぽいオブジェクトは Array.prototype.forEach.call()
として配列として振る舞うようにする方法、オブジェクトの場合は for...in
文や Object.keys
を利用した方法です。
$.each()
との違いは、コールバック関数の引数の順番や直接オブジェクトを使えない事、return false
でもループが止まらないことでしょうか。
Array.prototype.forEach
は関数を利用した方法なので、break
や continue
は使えませんが、continue
に関しては return
で代用できます。このメソッドでは、返り値を指定しても意味ありません。
ループを止める処理を行いたい場合、本来の使い方ではなくなってしまいますが、Array.prototype.some
で似たような事を行えます。
var kawaii142s = ['輿水幸子', '白坂小梅', 'あの子', '星輝子'];
/* jQuery */
$.each(kawaii142s, function (i, value) {
console.log(value);
if (value === 'あの子') {
console.log('フギャー!?');
return false;
}
});
// "輿水幸子"
// "白坂小梅"
// "あの子"
// "フギャー!?"
/* Array.prototype.some */
kawaii142s.some(function (value) {
console.log(value);
if (value === 'あの子') {
console.log('フギャー!?');
// return true; なので注意
return true;
}
});
// "輿水幸子"
// "白坂小梅"
// "あの子"
// "フギャー!?"
うーん、これはちょっとおすすめできないですね……
ちなみに、ECMAScript 2015 (ES6) では for...of
文が使えるので、break
や continue
も使えます。
for (let value of kawaii142s) {
console.log(value);
if (value === 'あの子') {
console.log('フギャー!?');
break;
}
}
// "輿水幸子"
// "白坂小梅"
// "あの子"
// "フギャー!?"
##$.extend()
オブジェクトのマージを行うメソッドです。
以下のような二つのオブジェクトがあるとします。
var
nickname01 = {
uzuki: 'しまむー',
rin: 'しぶりん',
ranko: 'らんらん',
riina: 'りーな',
miku: 'みくにゃん',
},
nickname02 = {
sachiko: 'さっちー',
kirari: 'きらりん',
riina: 'だりー',
mika: 'みかねえ',
rika: 'りかちー',
};
これらをマージしてみます。
$.extend(nickname01, nickname02);
// for...in 文で行う場合
for (var key in nickname02) {
nickname01[key] = nickname02[key];
}
// Object.keys() を利用する場合
Object.keys(nickname02).forEach(function (key) {
nickname01[key] = nickname02[key];
});
nickname01
は以下のようなオブジェクトになります
nickname01 = {
kirari: 'きらりん',
mika: 'みかねえ',
miku: 'みくにゃん',
ranko: 'らんらん',
riina: 'だりー',
rika: 'りかちー',
rin: 'しぶりん',
sachiko: 'さっちー',
uzuki: 'しまむー',
};
ちなみに、ECMAScript 2015 では Object.assign()
が $.extend()
とほぼ同じ処理をしてくれます。
let
nickname01 = {kirari: 'きらりん', mika: 'みかねえ', miku: 'みくにゃん'},
nickname02 = {ranko: 'らんらん', riina: 'だりー', rika: 'りかちー'},
nickname03 = {rin: 'しぶりん', sachiko: 'さっちー', uzuki: 'しまむー'};
// $.extend(nickname01, nickname02, nickname03); と同じ結果
Object.assign(nickname01, nickname02, nickname03);
$.extend(true, obj1, obj2)
とすることでディープマージを行えますが、ここでは簡単な方法のみ扱います。
##$.grep()
配列をフィルタリングするためのメソッドです。
var kawaii142s = ['輿水幸子', '白坂小梅', 'あの子', '星輝子'];
kawaii142s = $.grep(kawaii142s, function (value) {
return value !== 'あの子';
});
console.log(kawaii142s);
// ["輿水幸子", "白坂小梅", "星輝子"]
Array.prototype.filter
で同じことができます。
var kawaii142s = ['輿水幸子', '白坂小梅', 'あの子', '星輝子'];
kawaii142s = kawaii142s.filter(function (value) {
return value !== 'あの子';
});
console.log(kawaii142s);
// ["輿水幸子", "白坂小梅", "星輝子"]
##$.map()
配列の値を関数を通して新しい配列として出力するメソッドです。
var result = $.map([0, 1, 2, 3, 4], function (value) {
return value * 2;
});
console.log(result);
// [0, 2, 4, 6, 8]
Array.prototype.map
で同じことができます。
var result = [0, 1, 2, 3, 4].map(function (value) {
return value * 2;
});
console.log(result);
// [0, 2, 4, 6, 8]
##$.merge()
配列をマージする時に使うメソッドです。
var
asterisk = ['前川みく', '多田李衣菜'],
natsunana = ['木村夏樹', '安部菜々'];
$.merge(asterisk, natsunana);
console.log(asterisk);
// ["前川みく", "多田李衣菜", "木村夏樹", "安部菜々"]
これも簡単に書き直せます。(変数は上と同じ)
// Array.prototype.push.apply
asterisk.push.apply(asterisk, natsunana);
console.log(asterisk);
// ["前川みく", "多田李衣菜", "木村夏樹", "安部菜々"]
ECMAScript 2015 なら更にこのように書けます。
// Array.prototype.push
asterisk.push(...natsunana);
console.log(asterisk);
// ["前川みく", "多田李衣菜", "木村夏樹", "安部菜々"]
##$.contains()
要素の子要素に指定した要素が含まれているかの真偽値を返すメソッドです。
// document.documentElement の子要素に document.body は含まれている
$.contains(document.documentElement, document.body); // true
// document.body の子要素に document.documentElement は含まれていない
$.contains(document.body, document.documentElement); // false
// 自分自身は含まれない扱いになる
$.contains(document.body, document.body); // false
Node.contains()
を利用する事で代用できます。
// document.documentElement の子要素に document.body は含まれている
document.documentElement.contains(document.body); // true
// document.body の子要素に document.documentElement は含まれていない
document.body.contains(document.documentElement); // false
// 自分自身も含む扱いになる
document.body.contains(document.body); // true
// 自分自身は含まないようにする場合はこのような関数を用意する
function contains(parent, child) {
return parent !== child && parent.contains(child);
}
contains(document.body, document.body); // false
##$.inArray()
指定した値が配列に存在する場合、最初に見つけたもののインデックスを返します。
var lipps = ['速水奏', '城ヶ崎美嘉', '塩見周子', '宮本フレデリカ', '一ノ瀬志希'];
$.inArray('城ヶ崎美嘉', lipps); // 1
$.inArray('城ヶ崎莉嘉', lipps); // -1
Array.prototype.indexOf
を使用します。
var lipps = ['速水奏', '城ヶ崎美嘉', '塩見周子', '宮本フレデリカ', '一ノ瀬志希'];
lipps.indexOf('城ヶ崎美嘉'); // 1
lipps.indexOf('城ヶ崎莉嘉'); // -1
##$.isArray()
配列かどうかの真偽値を返すメソッドです。
$.isArray([]); // true
$.isArray({}); // false
Array.isArray([]); // true
Array.isArray({}); // false
##$.type()
指定したオブジェクトの型(クラス)を判定します。
$.type([]); // "array"
$.type({}); // "object"
$.type(''); // "string"
$.type(123); // "number"
$.type(function () {}); // "function"
Object.prototype.toString.call()
で同じことができます。
var toString = Object.prototype.toString;
function typeOf(obj) {
return toString.call(obj).slice(8, -1).toLowerCase();
}
typeOf([]); // "array"
typeOf({}); // "object"
typeOf(''); // "string"
typeOf(123); // "number"
typeOf(function () {}); // "function"
$.isPlainObject()
, $.isFunction()
といった判定系のメソッドはこの判定のショートハンドなので、こちらで事足ります。
##$.isEmptyObject()
指定したオブジェクトが空のオブジェクトかどうかの真偽値を返すメソッドです。
$.isEmptyObject({}); // true
$.isEmptyObject({yaminoma: '闇に飲まれよ!'}); // false
function isEmptyObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]' &&
Object.keys(obj).length === 0;
}
isEmptyObject({}); // true
isEmptyObject({yaminoma: '闇に飲まれよ!'}); // false
空のオブジェクトで Object.keys()
を使用すると空の配列になるのを利用した方法です。
##$.isWindow()
window
オブジェクトかどうかの真偽値を返すメソッドです。
$.isWindow(window); // true
$.isWindow(document); // false
function isWindow(obj) {
return !!obj && obj === obj.window;
}
isWindow(window); // true
isWindow(document); // false
window === window.window
を利用した方法です。
##$.isNumeric()
有効な数値かどうかの真偽値を返すメソッドです。
$.isNumeric(123); // true
$.isNumeric('123'); // true
$.isNumeric('-123'); // true
$.isNumeric(0x7b); // true
$.isNumeric('0x7b'); // true
$.isNumeric(1e10); // true
$.isNumeric('1e10'); // true
$.isNumeric(''); // false
$.isNumeric(null); // false
$.isNumeric(NaN); // false
$.isNumeric(Infinity); // false
var toString = Object.prototype.toString;
function typeOf(obj) {
return toString.call(obj).slice(8, -1).toLowerCase();
}
function isNumeric(obj) {
var type = typeOf(obj);
return (type === 'number' || type === 'string') && !isNaN(obj - parseFloat(obj));
}
isNumeric(123); // true
isNumeric('123'); // true
isNumeric('-123'); // true
isNumeric(0x7b); // true
isNumeric('0x7b'); // true
isNumeric(1e10); // true
isNumeric('1e10'); // true
isNumeric(''); // false
isNumeric(null); // false
isNumeric(NaN); // false
isNumeric(Infinity); // false
##$.parseHTML()
HTML文字列をノードリストに変換します。
// ノードの配列が返る
var nodeArray = $.parseHTML('<img src="./serval-chan.jpg" alt="サーバルちゃん">すっごーい!<span>なにそれなにそれー!</span>');
nodeArray.forEach(function (node) {
console.log(node.nodeName + ': ' + (node.outerHTML || node.textContent));
});
// "IMG: <img src="./serval-chan.jpg" alt="サーバルちゃん">"
// "#text: すっごーい!"
// "SPAN: <span>なにそれなにそれー!</span>"
function parseHTML(html) {
var tempBody = document.implementation.createHTMLDocument('').body;
tempBody.innerHTML = html;
return tempBody.childNodes;
}
// NodeList が返る
var nodeList = parseHTML('<img src="./serval-chan.jpg" alt="サーバルちゃん">すっごーい!<span>なにそれなにそれー!</span>');
nodeArray.forEach(function (node) {
console.log(node.nodeName + ': ' + (node.outerHTML || node.textContent));
});
// "IMG: <img src="./serval-chan.jpg" alt="サーバルちゃん">"
// "#text: すっごーい!"
// "SPAN: <span>なにそれなにそれー!</span>"
この二つの違いとして、$.parseHTML()
は要素の配列であり、jQueryを使わない方法では NodeList
になります。
##$.parseXML()
XML文をXMLドキュメントツリーに変換します。
var
xmlText = '<xml><title>凸レーション</title><member><name>諸星きらり</name><name>城ヶ崎莉嘉</name><name>赤城みりあ</name></member></xml>',
xmlDocument = $.parseXML(xmlText);
$('title', xmlDocument).text(); // "凸レーション"
$('member name', xmlDocument).each(function (i, element) {
console.log(i + ': ' + element.textContent);
});
// "0: 諸星きらり"
// "1: 城ヶ崎莉嘉"
// "2: 赤城みりあ"
var
xmlText = '<xml><title>凸レーション</title><member><name>諸星きらり</name><name>城ヶ崎莉嘉</name><name>赤城みりあ</name></member></xml>',
xmlDocument = new DOMParser().parseFromString(xmlText, 'application/xml');
xmlDocument.querySelector('title').textContent; // "凸レーション"
xmlDocument.querySelectorAll('member name').forEach(function (element, i) {
console.log(i + ': ' + element.textContent);
});
// "0: 諸星きらり"
// "1: 城ヶ崎莉嘉"
// "2: 赤城みりあ"
##$.parseJSON()
JSON形式の文字列をJavaScriptのオブジェクトへ変換します。
var json = '{"string":"たーのしー!","number":123,"array":["大丈夫","夜行性だから!"]}';
var obj = $.parseJSON(json);
// obj は以下のようなオブジェクトになる
obj = {
array: ['大丈夫', '夜行性だから!'],
number: 123,
string: 'たーのしー!',
};
var json = '{"string":"たーのしー!","number":123,"array":["大丈夫","夜行性だから!"]}';
var obj = JSON.parse(json);
// obj は以下のようなオブジェクトになる
obj = {
array: ['大丈夫', '夜行性だから!'],
number: 123,
string: 'たーのしー!',
};
##$.makeArray()
配列に似たオブジェクトを純粋な配列に変換します。
以下のような配列に似たオブジェクトがあったとします。
var
// オブジェクト
likeArray = {0: '島村卯月', 1: '渋谷凛', 2: '本田未央', length: 3},
// HTMLCollection
htmlCollection = document.getElementsByTagName('*'),
// NodeList
nodeList = document.querySelectorAll('*');
これらを配列に変換します。
// オブジェクト
likeArray = $.makeArray(likeArray); // ['島村卯月', '渋谷凛', '本田未央']
$.isArray(likeArray); // true
// HTMLCollection
htmlCollection = $.makeArray(htmlCollection); // [html, head, ...]
$.isArray(htmlCollection); // true
// NodeList
NodeList = $.makeArray(nodeList); // [html, head, ...]
$.isArray(nodeList); // true
// Array.prototype.slice を利用する
makeArray = Array.prototype.slice;
// オブジェクト
likeArray = makeArray.call(likeArray); // ['島村卯月', '渋谷凛', '本田未央']
Array.isArray(likeArray); // true
// HTMLCollection
htmlCollection = makeArray.call(htmlCollection); // [html, head, ...]
Array.isArray(htmlCollection); // true
// NodeList
NodeList = makeArray.call(nodeList); // [html, head, ...]
Array.isArray(nodeList); // true
ECMAScript 2015 では Array.from()
が使用できます。
// オブジェクト
likeArray = Array.from(likeArray); // ['島村卯月', '渋谷凛', '本田未央']
Array.isArray(likeArray); // true
// HTMLCollection
htmlCollection = Array.from(htmlCollection); // [html, head, ...]
Array.isArray(htmlCollection); // true
// NodeList
NodeList = Array.from(nodeList); // [html, head, ...]
Array.isArray(nodeList); // true
##$.proxy()
関数内で実行されるthisを任意のオブジェクトにします。
var individuals = {cute: '早坂美玲', cool: '森久保乃々', passion: '星輝子'};
function getMember(type) {
'use strict';
if (typeof this === 'undefined') {
return null;
}
return this[type];
}
// そのままでは this には何も入らない
getMember('cool'); // null
// Function.prototype.call() を使う
getMember.call(individuals, 'cool'); // "森久保乃々"
// $.proxy() を使う
var getIndividualsMember = $.proxy(getMember, individuals);
getIndividualsMember('cool'); // "森久保乃々"
Function.prototype.bind()
を使用します。
var individuals = {cute: '早坂美玲', cool: '森久保乃々', passion: '星輝子'};
function getMember(type) {
'use strict';
if (typeof this === 'undefined') {
return null;
}
return this[type];
}
// そのままでは this には何も入らない
getMember('cool'); // null
// Function.prototype.call() を使う
getMember.call(individuals, 'cool'); // "森久保乃々"
// Function.prototype.bind() を使う
var getIndividualsMember = getMember.bind(individuals);
getIndividualsMember('cool'); // "森久保乃々"
##$.globalEval()
グローバル空間で文字列のJavaScriptコードを実行させます。(使用注意)
$.globalEval("function goodMorning() {console.log('煩わしい太陽ね');}");
goodMorning(); // "煩わしい太陽ね"
function globalEval(code) {
var script = document.head.appendChild(document.createElement('script'));
script.text = code.trim();
document.head.removeChild(script);
}
globalEval("function goodMorning() {console.log('煩わしい太陽ね');}");
goodMorning(); // "煩わしい太陽ね"
##$.trim()
文字列の前後の改行や空白等を削除します。
var ranko = ' \n\n 我が友よ!\n煩わしい太陽ね!\n\n我に力を! \n ';
$.trim(ranko);
/*
"我が友よ!↵
煩わしい太陽ね!↵
↵
我に力を!"
*/
String.prototype.trim()
を使用します。
var ranko = ' \n\n 我が友よ!\n煩わしい太陽ね!\n\n我に力を! \n ';
ranko.trim();
/*
"我が友よ!↵
煩わしい太陽ね!↵
↵
我に力を!"
*/
##$.now()
現在の時刻(UNIX時間)を返します。
$.now(); // 例えば 1490094881993
Date.now(); // 例えば 1490094881993
##$.noop()
空の関数を返します。
$.noop; // function () {}
$.noop(); // undefined
var noop = function () {};
noop; // function () {}
noop(); // undefined
##$.ajax()
Ajax通信を行うメソッドです。
// get_text.php からテキストを受け取る
$.ajax({
type: 'get',
url: './get_text.php',
}).done(function (text) {
console.log(text);
}).fail(function () {
console.log('失敗したよ');
});
// post.php にテキストを送信
$.ajax({
type: 'post',
url: './post.php',
data: {
text: 'ラッキーさん、僕はお客さんじゃないよ',
},
}).done(function () {
console.log('送信完了');
}).fail(function () {
console.log('失敗したよ');
});
ECMAScript 2015 の Promise
が使える前提です。(ポリフィルは探せばあると思います)
かなり省いてます。(そしてあまり自信ない)
function ajax(url, type, data) {
return new Promise(function (resolve, reject) {
var
xhr = new XMLHttpRequest(),
params = '';
type = type || 'get';
if (data) {
for (key in data) {
params += encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) + '&';
}
params = params.slice(0, -1);
}
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 400) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.statusText));
}
};
xhr.onerror = function () {
reject(new Error(xhr.statusText));
};
if (type.toLowerCase() === 'post') {
xhr.open('post', url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhr.send(params);
} else {
if (params) {
url += '?' + params;
}
xhr.open('get', url, true);
xhr.send();
}
});
}
// get_text.php からテキストを受け取る
ajax('./get_text.php', 'get').then(function (text) {
console.log(text);
}, function () {
console.log('失敗したよ');
});
// post.php にテキストを送信
ajax('./post.php', 'post', {
text: 'ラッキーさん、僕はお客さんじゃないよ',
}).then(function () {
console.log('送信完了');
}, function () {
console.log('失敗したよ');
});
Fetch APIが使える場合はもっと簡単に書けます。が、まだ本格的には使えなさそう。
// get_text.php からテキストを受け取る
fetch('./get_text.php').then(function(response) {
// 文字列で受け取る
return response.text();
}, function () {
console.log('失敗したよ');
}).then(function(text) {
console.log(text);
});
// post.php にテキストを送信
fetch('./post.php', {
method: 'post',
body: new URLSearchParams('text=ラッキーさん、僕はお客さんじゃないよ'),
}).then(function () {
console.log('送信完了');
}, function () {
console.log('失敗したよ');
});
Ajax通信の中断やテキスト以外の扱い等については省略します。
#DOM操作系メソッド
jQueryといえばやはりこちらがメインですよね。よく使いそうなものだけ取り上げています。
##$(function () {}), $(document).ready(function () {})
DOM構築が完了した後に実行します。これをやらないとうまく要素が取得できない原因になります。
// 通常
$(function () {
// do something
});
// 非推奨
$(document).ready(function () {
// do something
});
document.addEventListener('DOMContentLoaded', function () {
// do something
});
document.addEventListener('load', function () {});
では、外部ファイルがすべて読み込みが完了するまで実行されないので、意図した動作にならない可能性があります。
##$('<tag>'), $('<tag attribute="value">content</tag>')
新しいHTML要素を生成します。
配列に似たjQueryオブジェクトが返ります。
// span要素の生成
$('<span>');
$('<span/>');
$('<span></span>');
// 中にテキストを含めたp要素の生成
$('<p>よぉこそぉ↑ジャパリカフェへ〜!</p>');
$('<p>').text('よぉこそぉ↑ジャパリカフェへ〜!');
// img要素の生成
$('<img src="./japaripark.jpg" alt="ジャパリパーク">');
$('<img>').attr({
src: './japaripark.jpg',
alt: 'ジャパリパーク',
});
// 生成した要素を #targetBlock に追加
$('<div>どうぞどうぞ! ゆっぐりしていってぇ!</div>').appendTo('#targetBlock');
// span要素の生成
var span = document.createElement('span');
// 中にテキストを含めたp要素の生成
var paragraph = document.createElement('p');
paragraph.textContent = 'よぉこそぉ↑ジャパリカフェへ〜!';
// img要素の生成(パターン1)
var img01 = document.createElement('img');
img01.src = './japaripark.jpg';
img01.alt = 'ジャパリパーク';
// img要素の生成(パターン2)
var img02 = new Image();
img02.src = './japaripark.jpg';
img02.alt = 'ジャパリパーク';
// 生成した要素を #targetBlock に追加
var div = document.createElement('div');
div.textContent = 'どうぞどうぞ! ゆっぐりしていってぇ!';
document.getElementById('targetBlock').appendChild(div);
##$('selector')
HTML要素を取得する方法です。CSSセレクタのように書けるので非常に便利ですよね。
配列に似たjQueryオブジェクトが返ります。
// idが "mainFooter" の要素を取得
$('#mainFooter');
// class名が "entries" の要素を取得
$('.entries');
// div要素を取得
$('div');
// article要素の子要素であるp要素を取得
$('article p');
$('article').find('p');
// ul要素とol要素の取得
$('ul, ol');
// チェックが付いたinput要素の取得
$('input:checked');
$('input').filter(':checked');
// target属性のないa要素を取得
$('a:not([target])');
$('a').not('[target]');
JavaScriptでは様々な取得方法があります。
document.getElementById
と document.querySelector
はHTML要素が、それ以外は配列に似た HTMLCollection
や NodeList
が返ります。
// idが "mainFooter" の要素を取得
document.getElementById('mainFooter'); // 処理が速い
document.querySelector('#mainFooter');
// class名が "entries" の要素を取得
document.getElementsByClassName('entries'); // 処理が速い
document.querySelectorAll('.entries');
// div要素を取得
document.getElementsByTagName('div'); // 処理が速い
document.querySelectorAll('div');
// article要素の子要素であるp要素を取得
document.querySelectorAll('article p');
// ul要素とol要素の取得
document.querySelectorAll('ul, ol');
// チェックが付いたinput要素の取得
document.querySelectorAll('input:checked');
// target属性のないa要素を取得
document.querySelectorAll('a:not([target])');
document.querySelectorAll
がほぼ同じ働きをしてくれています。
document.getElementsByTagName
や document.getElementsByClassName
が返す HTMLCollection
は動的な要素のリストで、document.querySelectorAll
が返す NodeList
は静的な要素のリストです。
何が違うのかというと、操作している途中で要素が追加されたりすると HTMLCollection
の中身と length
が変化するのに対して、NodeList
は取得した当時の値を保持したままです。なので、扱いに注意が必要です。
また、NodeList
は配列の Array.prototype.forEach()
と同じように NodeList.forEach()
が使用可能です。
以降、複数パターンを書くと煩雑になるので、基本的に単体のHTML要素の取得には document.querySelector
を、複数のHTML要素の取得には document.querySelectorAll
を使用する方法で解説します。
(実際には状況によって document.getElementById
, document.getElementsByTagName
, document.getElementsByClassName
なども使い分けるなどしましょう)
##.each()
取得した要素のループ処理を行うメソッドです。
// '.article p' のループ処理
$('.article p').each(function (i, element) {
// do something
});
NodeList.forEach()
が使えます。引数がjQueryと逆なので注意。
// '.article p' のループ処理
document.querySelectorAll('.article p').forEach(function (element, i) {
// do something
});
IEなどでは NodeList.forEach()
が使えないので、Array.prototype.forEach()
で代用ができます。
/* Array.prototype.forEach.call() でなんとかする */
var forEach = Array.prototype.forEach;
// '.article p' のループ処理
forEach.call(document.querySelectorAll('.article p'), function (element, i) {
// do something
});
/* いっその事同じコードで書けるようにする */
if (!NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
// '.article p' のループ処理
document.querySelectorAll('.article p').forEach(function (element, i) {
// do something
});
ちなみに、NodeList
は ECMAScript 2015 の for...of
文も使用できます。
以降のコードでは、NodeList.forEach()
を使用します。
##.find()
子要素(孫要素、ひ孫要素なども含む)を取得します。
// #mainNavigation の li を取得
$('#mainNavigation').find('li');
// .entries の h2 と h3 を取得
$('.entries').find('h2, h3');
/* 本来ならばこのように書く方がわかりやすい */
// #mainNavigation の li を取得
$('#mainNavigation li');
// .entries の h2 と h3 を取得
$('.entries h2, .entries h3');
/* あえて複雑な書き方をする場合 */
// #mainNavigation の li を取得(4通り)
document.getElementById('mainNavigation').getElementsByTagName('li'); // 処理が速い
document.getElementById('mainNavigation').querySelectorAll('li');
document.querySelector('#mainNavigation').getElementsByTagName('li');
document.querySelector('#mainNavigation').querySelectorAll('li');
// .entries の h2 と h3 を取得(配列にHTML要素を入れる方法)
var elements = [];
document.querySelectorAll('.entries').forEach(function (element) {
elements.push.apply(elements02, element.querySelectorAll('h2, h3'));
});
/// elements に h2 と h3 が入る
/* 本来ならばこのように書く方がわかりやすい */
// #mainNavigation の li を取得
document.querySelectorAll('#mainNavigation li');
// .entries の h2 と h3 を取得
document.querySelectorAll('.entries h2, .entries h3');
##.html(), .text(), .empty()
指定した要素内のHTMLやテキストを取得・変更・空にします。
var $welcome = $('#welcome');
// .welcome 内のHTMLを取得
$welcome.html(); // 例えば "<b>ようこそ!</b>"
// .welcome 内のテキストを取得
$welcome.text(); // 例えば "ようこそ!"
// .welcome 内のHTMLを変更
$welcome.html('<b>いらっしゃぁい!</b>');
// .welcome 内のテキストを変更
$welcome.text('よぉこそぉ↑ジャパリカフェへ〜!');
// .welcome 内を空にする
$welcome.empty();
var welcome = document.querySelector('#welcome');
// .welcome 内のHTMLを取得
welcome.innerHTML; // 例えば "<b>ようこそ!</b>"
// .welcome 内のテキストを取得
welcome.textContent; // 例えば "ようこそ!"
// .welcome 内のHTMLを変更
welcome.innerHTML = '<b>いらっしゃぁい!</b>';
// .welcome 内のテキストを変更
welcome.textContent = 'よぉこそぉ↑ジャパリカフェへ〜!';
// .welcome 内を空にする
welcome.textContent = '';
##.attr(), .removeAttr()
要素の属性の値を取得、属性の追加・変更・削除を行います。
// #mainImage のalt属性を取得
$('#mainImage').attr('alt'); // 例えば "けものフレンズ"
// .targetLink にtarget属性を追加する
$('.targetLink').attr('target', '_blank');
$('.targetLink').attr({target: '_blank'});
// .targetLink のtarget属性を取り除く
$('.targetLink').removeAttr('target');
// #mainImage のalt属性を取得
document.querySelector('#mainImage').getAttribute('alt'); // 例えば "けものフレンズ"
// .targetLink にtarget属性を追加する
document.querySelectorAll('.targetLink').forEach(function (element) {
element.setAttribute('target', '_blank');
});
// .targetLink のtarget属性を取り除く
document.querySelectorAll('.targetLink').forEach(function (element) {
element.removeAttribute('target');
});
##.addClass(), .removeClass(), .toggleClass(), .hasClass()
要素のクラス名関係の操作です。
var $elements = $('li a');
// 'li a' にクラス 'listLink' を追加
$elements.addClass('listLink');
// 'li a' のクラス 'listLink' を削除
$elements.removeClass('listLink');
// 'li a' のクラス 'listLink' がない場合は追加し、ある場合は削除する
$elements.toggleClass('listLink');
// #targetBlock にクラス 'listLink' が存在するかの真偽値
$('#targetBlock').hasClass('listLink'); // 例えば "false"
var elements = document.querySelectorAll('li a');
// 'li a' にクラス 'listLink' を追加
elements.forEach(function (element) {
element.classList.add('listLink');
});
// 'li a' のクラス 'listLink' を削除
elements.forEach(function (element) {
element.classList.remove('listLink');
});
// 'li a' のクラス 'listLink' がない場合は追加し、ある場合は削除する
elements.forEach(function (element) {
element.classList.toggle('listLink');
});
// #targetBlock にクラス 'listLink' が存在するかの真偽値
document.querySelector('#targetBlock').classList.contains('listLink'); // 例えば "false"
##.css()
要素のスタイルを取得したり、スタイルを適用します。
// 最初に取得できる .redBox のスタイルを取得
$('.redBox').css('background-color'); // 例えば "rgb(255, 0, 0)"
$('.redBox').css('backgroundColor'); // 例えば "rgb(255, 0, 0)"
// .targetBox にスタイルを適用
$('.targetBox').css('margin-bottom', 50);
$('.targetBox').css('marginBottom', 50);
$('.targetBox').css({'margin-bottom': 50});
$('.targetBox').css({marginBottom: 50});
// 最初に取得できる .redBox のスタイルを取得
var
redBox = document.querySelector('.redBox'),
redBoxStyle = window.getComputedStyle(redBox); // getComputedStyle を使う
redBoxStyle.backgroundColor; // 例えば "rgb(255, 0, 0)"
redBoxStyle.getPropertyValue('background-color'); // 例えば "rgb(255, 0, 0)"
// .targetBox にスタイルを適用
document.querySelectorAll('.targetBox').forEach(function (element) {
element.style.marginBottom = '50px';
// チェインケースの場合
// element.style.setProperty('margin-bottom', '50px');
});
window.getComputedStyle()
については、自分が前に書いたものを見てもらうと分かると思います。
window.getComputedStyle() で要素のスタイルを取得する
##.prop()
要素のプロパティを取得・変更します。
// 取得した要素の nodeName を取得する
$('.mainArticle').prop('nodeName'); // 例えば "ARTICLE"
// 2番目のチェックボックスにチェックを入れる
$('input[type="checkbox"]').eq(1).prop('checked', true);
$('input[type="checkbox"]').eq(1).prop({checked: true});
// 複数のテキストフォームを空にして disabled にする
$('input[type="text"]').prop({
value: '',
disabled: true,
});
// 取得した要素の nodeName を取得する
var mainArticle = document.querySelector('.mainArticle');
mainArticle.nodeName; // 例えば "ARTICLE"
// 2番目のチェックボックスにチェックを入れる
var checkbox = document.querySelectorAll('input[type="checkbox"]');
checkbox[1].checked = true;
// 複数のテキストフォームを空にして disabled にする
var inputText = document.querySelectorAll('input[type="text"]');
inputText.forEach(function (element) {
element.value = '';
element.disabled = true;
});
##.data()
要素に紐づけられたデータを設定・取得します。
このメソッドは要素の data-*
属性の値を取得しますが、jQueryは独自にデータを管理するので完全な互換性があるわけではありません。
jQueryでは文字列だけでなく数値や配列、オブジェクトといったものも紐づけられるのに対し、ネイティブな実装ではすべて文字列として扱われます。
以下のようなHTMLがあったとします。
<div id="toki" data-name="Japanese crester ibis" data-cites-year="1973">わたしはトキ 仲間を探してる どこにいるの仲間たち</div>
var $toki = $('#toki');
// data-name の値を取得
$toki.data('name'); // "Japanese crester ibis"
$.type($toki.data('name')); // "string"
// data-cites-year の値を取得
$toki.data('citesYear'); // 1973
$toki.data('cites-year'); // 1973
$.type($toki.data('citesYear')); // "number"
// classification という名前のデータの追加(オブジェクトを追加)
$toki.data('classification', {
class: 'Aves',
order: 'Pelecaniformes',
family: 'Threskiornithidae',
});
$.type($toki.data('classification')); // "object"
// #toki に紐づけられたデータを取得
var tokiData = $toki.data();
// tokiData は以下のようなオブジェクトが入っている
tokiData = {
name: 'Japanese crester ibis',
citesYear: 1973,
classification: {
class: 'Aves',
order: 'Pelecaniformes',
family: 'Threskiornithidae',
},
};
var toString = Object.prototype.toString;
function typeOf(obj) {
return toString.call(obj).slice(8, -1).toLowerCase();
}
var toki = document.querySelector('#toki');
// data-name の値を取得
toki.dataset.name; // "Japanese crester ibis"
typeOf(toki.dataset.name); // "string"
// data-cites-year の値を取得
toki.dataset.citesYear; // "1973"
typeOf(toki.dataset.citesYear); // "string" ←!!
// classification という名前のデータの追加(オブジェクトを追加してみる)
toki.dataset.classification = {
class: 'Aves',
order: 'Pelecaniformes',
family: 'Threskiornithidae',
};
typeOf(toki.dataset.classification); // "string" ←!!
// #toki に紐づけられたデータを取得
var tokiData = toki.dataset;
// tokiData は以下のような DOMStringMap という名前のオブジェクトが入っている
tokiData = {
name: 'Japanese crester ibis',
citesYear: '1973',
classification: '[object Object]', // object は文字列に変換されるため
};
HTMLElement.dataset
は文字列しか扱えないのがわかります。
##.eq()
n番目の要素を取り出します。
var $lists = $('#linkList li');
// '#linkList li' の4つ目を取り出す
$lists.eq(3);
// '#linkList li' の後ろから2つ目を取り出す
$lists.eq(-2);
var lists = document.querySelectorAll('#linkList li');
// '#linkList li' の4つ目を取り出す
lists[3];
// '#linkList li' の後ろから2つ目を取り出す
lists[lists.length - 2];
##.index()
指定した要素が取得した要素の何番目にあるかを調べます。
以下のようなHTMLがあったとします、
<ul class="ppp">
<li class="royal">プリンセス</li>
<li class="emperor">コウテイ</li>
<li class="gentoo">ジェーン</li>
<li class="rockhopper">イワビー</li>
<li class="humboldt">フルル</li>
</ul>
var $rockhopper = $('.rockhopper');
$('.ppp li').index($rockhopper); // 3
Array.prototype.indexOf
を利用します。
var indexOf = Array.prototype.indexOf;
var rockhopper = document.querySelector('.rockhopper');
indexOf.call(document.querySelectorAll('.ppp li'), rockhopper); // 3
##.slice()
指定した範囲の要素リストを作ります。
以下のようなHTMLがあったとします、
<ul class="ppp">
<li class="royal">プリンセス</li>
<li class="emperor">コウテイ</li>
<li class="gentoo">ジェーン</li>
<li class="rockhopper">イワビー</li>
<li class="humboldt">フルル</li>
</ul>
var $ppp = $('.ppp li');
$ppp.slice(1, 3);
// [li.emperor, li.gentoo] のjQueryオブジェクトになる
$ppp.slice(-2);
// [li.rockhopper, li.humboldt] のjQueryオブジェクトになる
$ppp.slice(0, -3);
// [li.royal, li.emperor] のjQueryオブジェクトになる
Array.prototype.slice
を利用します。
var slice = Array.prototype.slice;
var ppp = document.querySelectorAll('.ppp li');
slice.call(ppp, 1, 3);
// [li.emperor, li.gentoo] の配列になる
slice.call(ppp, -2);
// [li.rockhopper, li.humboldt] の配列になる
slice.call(ppp, 0, -3);
// [li.royal, li.emperor] の配列になる
##.first(), .last()
取得した要素リストの最初・最後の要素を取り出します。
var $lists = $('#linkList li');
// '#linkList li' の最初の要素を取り出す
$lists.first();
// '#linkList li' の最後の要素を取り出す
$lists.last();
var lists = document.querySelectorAll('#linkList li');
// '#linkList li' の最初の要素を取り出す
lists[0];
// '#linkList li' の最後の要素を取り出す
lists[lists.length - 1];
##.filter(), .not()
取得した要素リストを特定の条件に当てはまる・当てはまらないかでフィルタリングします。
var $variousElement = $('.variousElement');
// .variousElement で span のみを取得
$('.variousElement').filter('span');
// .variousElement で span 以外を取得
$('.variousElement').not('span');
var $input = $('input');
// input属性の :checked のみを取得
$('input').filter(':checked');
// input属性の :disabled 以外を取得
$('input').not(':disabled');
/* 本来ならばこのように書く方がわかりやすい */
// input属性の :checked のみを取得
$('input:checked');
// input属性の :disabled 以外を取得
$('input:not(:disabled)');
// .variousElement で span のみを取得
document.querySelectorAll('span.variousElement');
// .variousElement で span 以外を取得
document.querySelectorAll('.variousElement:not(span)');
// input属性の :checked のみを取得
document.querySelectorAll('input:checked');
// input属性の :disabled 以外を取得
document.querySelectorAll('input:not(:disabled)');
##.has()
指定した要素を子に持つ要素だけを取得します。
以下のようなHTMLがあったとします。
<ul class="words">
<li>おいしいものを食べてこその人生なのです</li>
<li>へーき、へーき!<br>フレンズによって得意なこと違うから!</li>
<li>がおー! たべちゃうぞー!</li>
<li>早く追いかけるのだ!<br>パークの危機なのだ!</li>
<li>アライさん、またやってしまったねぇ</li>
</ul>
br要素を持つli要素だけ取得してみます。
var $hasBreak = $('.words li').has('br');
$hasBreak.each(function (i, element) {
console.log(element.textContent);
});
// "へーき、へーき!フレンズによって得意なこと違うから!"
// "早く追いかけるのだ!パークの危機なのだ!"
var filter = Array.prototype.filter;
var words = document.querySelectorAll('.words li');
var hasBreak = filter.call(words, function (element) {
return !!element.querySelector('br');
});
hasBreak.forEach(function (element) {
console.log(element.textContent);
});
// "へーき、へーき!フレンズによって得意なこと違うから!"
// "早く追いかけるのだ!パークの危機なのだ!"
##.children()
要素の直下にある子要素を取得します。
// .entries 直下の子要素を取得
$('.entries').children();
// .entries 直下の div を取得
$('.entries').children('div');
/* 本来ならばこのように書く方がわかりやすい */
// .entries 直下の子要素を取得
$('.entries > *');
// .entries 直下の div を取得
$('.entries > div');
// .entries 直下の子要素を取得
document.querySelectorAll('.entries > *');
// .entries 直下の div を取得
document.querySelectorAll('.entries > div');
##.parent()
要素の親要素を取得します。
// .children の親要素の取得
$('.children').parent();
// .children の親要素の取得
var parents = [];
document.querySelectorAll('.children').forEach(function (element) {
parents.push(element.parentNode);
});
/// 重複しているかもしれないので filter を使う
parents = parents.filter(function (element, i) {
return parents.indexOf(element) === i;
});
##.parents()
現在の要素から <html> まで遡ります。
以下のようなHTMLがあったとします。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>テスト</title>
</head>
<body>
<ul class="level1">
<li class="level1-1">わたしはトキ 仲間を探してる</li>
<li class="level1-2">どこにいるの仲間たち
<ul class="level2">
<li class="level2-1">わたしの仲間探してくださいあ あ仲間……</li>
</ul>
</li>
</ul>
</body>
</html>
// .level2-1 からさかのぼっていく
var $parents = $('.level2-1').parents();
// $parents はこのようなリストになる(実際にはjQueryオブジェクトです)
// {0: ul.level2, 1: li.level1-2, 2: ul.level1, 3: body, 4: html}
// .level2-1 からさかのぼっていく
var
cursor = document.querySelector('.level2-1').parentNode,
parents = [];
for (; !!cursor && cursor.nodeType !== 9; cursor = cursor.parentNode) {
parents.push(cursor);
}
// parents はこのような配列になる
// [ul.level2, li.level1-2, ul.level1, body, html]
##.closest()
現在の要素から最初にマッチする要素まで遡ります。
以下のようなHTMLがあったとします。
<ul class="level1">
<li class="level1-1">わたしはトキ</li>
<li class="level1-2 find">仲間を探してる
<ul class="level2">
<li class="level2-1 where">どこにいるの仲間たち</li>
<li class="level2-2 find">わたしの仲間探してください
<ul class="level3">
<li class="level3-1">ああ仲間……</li>
</ul>
</li>
</ul>
</li>
</ul>
// この場合 ul.level3 になる
$('.level3-1').closest('ul');
// この場合 li.level2-2 になる
$('.level3-1').closest('.find');
// この場合 li.level1-2 になる
$('.level2-1').closest('.find');
// 何も取得しない
$('.level3-1').closest('.where');
$('.level1-1').closest('li');
// 自分自身を取得
$('.level2-1').closest('li');
$('.level3-1').closest('li');
Element.closest()
を使用します。
// Element.closest() を利用するが、対応していないIE/Edgeのためにポリフィルも用意する
if (!Element.prototype.closest) {
Element.prototype.closest = function (selector) {
var closest = null;
for (var cursor = this; !!cursor && cursor.nodeType !== 9; cursor = cursor.parentNode) {
if (cursor.msMatchesSelector(selector)) {
closest = cursor;
break;
}
}
return closest;
};
}
// この場合 ul.level3 になる
document.querySelector('.level3-1').closest('ul');
// この場合 li.level2-2 になる
document.querySelector('.level3-1').closest('.find');
// この場合 li.level1-2 になる
document.querySelector('.level2-1').closest('.find');
// 何も取得しない
document.querySelector('.level3-1').closest('.where');
document.querySelector('.level1-1').closest('li');
// 自分自身を取得
document.querySelector('.level2-1').closest('li');
document.querySelector('.level3-1').closest('li');
##.next(), .prev()
要素の前後にある要素を取得します。
// .target の後にある要素の取得
$('.target').next();
// .target の前にある要素の取得
$('.target').prev();
// .target の後にある要素の取得
document.querySelectorAll('.target + *');
// .target の後にある要素の取得その2(nextElements に入る)
var nextElements = [];
document.querySelectorAll('.target').forEach(function (element) {
if (element.nextElementSibling) {
nextElements.push(element.nextElementSibling);
}
});
// .target の前にある要素の取得(prevElements に入る)
var prevElements = [];
document.querySelectorAll('.target').forEach(function (element) {
if (element.previousElementSibling) {
prevElements.push(element.previousElementSibling);
}
});
##.siblings(), .nextAll(), .prevAll()
自分以外の兄弟要素を取得します。
以下のようなHTMLがあったとします。
<ul>
<li class="item01">わたしはトキ</li>
<li class="item02">仲間を探してる</li>
<li class="item03">どこにいるの</li>
<li class="item04">仲間たち</li>
<li class="item05">わたしの仲間</li>
<li class="item06">さがしてください</li>
<li class="item07">ああ仲間……</li>
</ul>
var $item04 = $('.item04');
// .item04 の兄弟要素を取得
$item04.siblings(); // li.item04 以外のli要素のリストになる
// .item04 から後の兄弟要素の取得
$item04.nextAll(); // [li.item05, li.item06, li.item07]
// .item04 より前の兄弟要素の取得
$item04.prevAll(); // [li.item03, li.item02, li.item01]
var array = Array.prototype;
var item04 = document.querySelector('.item04');
// .item04 の兄弟要素を取得
var siblings = array.filter.call(item04.parentNode.children, function (element) {
return element !== item04;
});
/// siblings は li.item04 以外のli要素の配列になる
// .item04 から後の兄弟要素の取得(簡単な記述)
document.querySelectorAll('.item04 ~ *'); // [li.item05, li.item06, li.item07]
// .item04 から後の兄弟要素の取得(複雑な記述の例)
var nextAll = array.slice.call(item04.parentNode.children, array.indexOf.call(item04.parentNode.children, item04) + 1);
console.log(nextAll); // [li.item05, li.item06, li.item07]
// .item04 より前の兄弟要素の取得
var prevAll = array.slice.call(item04.parentNode.children, 0, array.indexOf.call(item04.parentNode.children, item04)).reverse();
console.log(prevAll); // [li.item03, li.item02, li.item01]
##.clone()
要素を複製します。
// .sampleElement を複製
$('.sampleElement').clone();
// .sampleElement を複製(cloneElements に入る)
var cloneElements = [];
document.querySelectorAll('.sampleElement').forEach(function (element) {
cloneElements.push(element.cloneNode(true));
});
// .sampleElement(単体)を複製
document.querySelector('.sampleElement').cloneNode(true);
##.remove()
要素をDOMから取り除きます。(削除ではない)
// .ignore を取り除く
$('.ignore').remove();
// .ignore を取り除く
document.querySelectorAll('.ignore').forEach(function (element) {
element.parentNode.removeChild(element);
// IE以外のブラウザではこの方法も使える
// element.remove();
});
##.before(), .prepend(), .append(), .after()
指定した要素にHTMLや要素を挿入します。
以下のようなHTMLがあったとします。
<p id="naninomu">ねえなんにぃのんむぅ</p>
<div id="targetBlock">
<p>ゆっぐりしてってぇ!</p>
</div>
これにいろいろ挿入してみます。
var $targetBlock = $('#targetBlock');
// #targetBlock の前にHTMLを挿入
$targetBlock.before('<p id="p01">ふわああぁ!</p>');
// #targetBlock 内の先頭にHTMLを挿入
$targetBlock.prepend('<p id="p02">どうぞどうぞ!</p>');
// #targetBlock 内の一番後ろにHTMLを挿入
$targetBlock.append('<p id="p03">いやま゛っ↓てたよぉ!</p>');
// #targetBlock の後ろにHTMLを挿入
$targetBlock.after('<p id="p04">色々あるよぉ</p>');
// #targetBlock の前に、生成した要素を挿入
var $paragraph01 = $('<p id="p05">いらっしゃぁい!</p>');
$targetBlock.before($paragraph01);
// #targetBlock 内の先頭に、生成した要素を挿入
var $paragraph02 = $('<p id="p06">よぉこそぉ↑ジャパリカフェへ〜!</p>');
$targetBlock.prepend($paragraph02);
// #targetBlock 内の一番後ろに、生成した要素を挿入
var $paragraph03 = $('<p id="p07">やっとお客さんが来てくれたゆぉ!</p>');
$targetBlock.append($paragraph03);
// #targetBlock の後ろに、生成した要素を挿入
var $paragraph04 = $('<p id="p08">嬉しいなあ!</p>');
$targetBlock.after($paragraph04);
// #p08 の後ろに、#naninomu を挿入(移動)
$('#p08').after($('#naninomu'));
var targetBlock = document.querySelector('#targetBlock');
// #targetBlock の前にHTMLを挿入
targetBlock.insertAdjacentHTML('beforebegin', '<p id="p01">ふわああぁ!</p>');
// #targetBlock 内の先頭にHTMLを挿入
targetBlock.insertAdjacentHTML('afterbegin', '<p id="p02">どうぞどうぞ!</p>');
// #targetBlock 内の一番後ろにHTMLを挿入
targetBlock.insertAdjacentHTML('beforeend', '<p id="p03">いやま゛っ↓てたよぉ!</p>');
// #targetBlock の後ろにHTMLを挿入
targetBlock.insertAdjacentHTML('afterend', '<p id="p04">色々あるよぉ</p>');
// #targetBlock の前に、生成した要素を挿入
var paragraph01 = document.createElement('p');
paragraph01.id = 'p05';
paragraph01.textContent = 'いらっしゃぁい!';
targetBlock.parentNode.insertBefore(paragraph01, targetBlock);
/// 「#targetBlock の親要素」内にある子要素の #targetBlock の前に paragraph01 を挿入、ということ
// #targetBlock 内のの先頭に、生成した要素を挿入
var paragraph02 = document.createElement('p');
paragraph02.id = 'p06';
paragraph02.textContent = 'よぉこそぉ↑ジャパリカフェへ〜!';
targetBlock.insertBefore(paragraph02, targetBlock.firstChild);
/// #targetBlock 内にある最初の子要素の前に paragraph01 を挿入、ということ
// #targetBlock 内の一番後ろに、生成した要素を挿入
var paragraph03 = document.createElement('p');
paragraph03.id = 'p07';
paragraph03.textContent = 'やっとお客さんが来てくれたゆぉ!';
targetBlock.appendChild(paragraph03);
// #targetBlock の後ろに、生成した要素を挿入
var paragraph04 = document.createElement('p');
paragraph04.id = 'p08';
paragraph04.textContent = '嬉しいなあ!';
targetBlock.parentNode.insertBefore(paragraph04, targetBlock.nextSibling);
/// 「#targetBlock の親要素」内にある子要素の #targetBlock の
/// 次にあるノード(テキストや要素など)の前に挿入、ということ
// #p08 の後ろに、#naninomu を挿入(移動)
var p08 = document.querySelector('#p08');
p08.parentNode.insertBefore(document.querySelector('#naninomu'), p08.nextSibling);
最終的にHTMLはこのような感じになります。
<p id="p01">ふわああぁ!</p>
<p id="p05">いらっしゃぁい!</p>
<div id="targetBlock">
<p id="p06">よぉこそぉ↑ジャパリカフェへ〜!</p>
<p id="p02">どうぞどうぞ!</p>
<p>ゆっぐりしてってぇ!</p>
<p id="p03">いやま゛っ↓てたよぉ!</p>
<p id="p07">やっとお客さんが来てくれたゆぉ!</p>
</div>
<p id="p08">嬉しいなあ!</p>
<p id="naninomu">ねえなんにぃのんむぅ</p>
<p id="p04">色々あるよぉ</p>
このサンプルでは生成した要素を挿入していますが、既にDOM上にある要素も同じように扱えます。
##.insertBefore(), .prependTo(), .appendTo(), .insertAfter()
要素を指定した要素に挿入します。
以下のようなHTMLがあったとします。
<p id="yukkuri">ゆっぐりしてってぇ!</p>
<div id="targetBlock">
<p>よぉこそぉ↑ジャパリカフェへ〜!</p>
</div>
これにいろいろ挿入してみます。
// 生成した要素を #targetBlock の前に挿入
$('<p id="p01">ふわああぁ!</p>').insertBefore('#targetBlock');
// 生成した要素を #targetBlock 内の先頭に挿入
$('<p id="p02">いらっしゃぁい!</p>').prependTo('#targetBlock');
// 生成した要素を #targetBlock 内の一番後ろに挿入
$('<p id="p03">どうぞどうぞ!</p>').appendTo('#targetBlock');
// 生成した要素を #targetBlock の後ろに挿入
$('<p id="p04">いやま゛っ↓てたよぉ!</p>').insertAfter('#targetBlock');
var targetBlock = document.querySelector('#targetBlock');
/* 考えは .before(), .prepend(), .append(), .after() と同じ*/
// 生成した要素を #targetBlock の前に挿入
var paragraph01 = document.createElement('p');
paragraph01.id = 'p01';
paragraph01.textContent = 'ふわああぁ!';
targetBlock.parentNode.insertBefore(paragraph01, targetBlock);
// 生成した要素を #targetBlock 内の先頭に挿入
var paragraph02 = document.createElement('p');
paragraph02.id = 'p02';
paragraph02.textContent = 'いらっしゃぁい!';
targetBlock.insertBefore(paragraph02, targetBlock.firstChild);
// 生成した要素を #targetBlock 内の一番後ろに挿入
var paragraph03 = document.createElement('p');
paragraph03.id = 'p03';
paragraph03.textContent = 'どうぞどうぞ!';
targetBlock.appendChild(paragraph03);
// 生成した要素を #targetBlock の後ろに挿入
var paragraph04 = document.createElement('p');
paragraph04.id = 'p04';
paragraph04.textContent = 'いやま゛っ↓てたよぉ!';
targetBlock.parentNode.insertBefore(paragraph04, targetBlock.nextSibling);
// #p04 の前に、#yukkuri を挿入(移動)
var p04 = document.querySelector('#p04');
p04.parentNode.insertBefore(document.querySelector('#yukkuri'), p04);
最終的にHTMLはこのような感じになります。
<p id="p01">ふわああぁ!</p>
<div id="targetBlock">
<p id="p02">いらっしゃぁい!</p>
<p>よぉこそぉ↑ジャパリカフェへ〜!</p>
<p id="p03">どうぞどうぞ!</p>
</div>
<p id="yukkuri">ゆっぐりしてってぇ!</p>
<p id="p04">いやま゛っ↓てたよぉ!</p>
##.wrap(), .wrapAll(), .wrapInner(), .unwrap()
特定の要素を指定した要素で包んだり、親要素を取り除いたりします。
以下のようなHTMLがあったとします。
<section class="images01">
<img src="./kaban.jpg" alt="かばん">
<img src="./serval.jpg" alt="サーバル">
<img src="./fennec.jpg" alt="フェネック">
<img src="./common-raccoon.jpg" alt="アライさん">
</section>
<section class="images02">
<img src="./kaban.jpg" alt="かばん">
<img src="./serval.jpg" alt="サーバル">
<img src="./fennec.jpg" alt="フェネック">
<img src="./common-raccoon.jpg" alt="アライさん">
</section>
これにいろいろ操作してみます。
// '.images01 img' をひとつひとつdiv要素で包む
$('.images01 img').wrap('<div>');
// '.images02 img' をまとめてdiv要素で包む
$('.images02 img').wrapAll('<div>');
// .images01 の子要素をspan要素で包む
$('.images01').wrapInner('<span>');
// 'section div' の親要素(要するに section)を取り除く
$('section div').unwrap();
// '.images01 img' をひとつひとつdiv要素で包む
document.querySelectorAll('.images01 img').forEach(function (element) {
var wrapElement = document.createElement('div');
element.parentNode.insertBefore(wrapElement, element);
wrapElement.appendChild(element);
});
// '.images02 img' をまとめてdiv要素で包む
var
images02 = document.querySelectorAll('.images02 img'),
wrapElement = document.createElement('div');
images02[0].parentNode.insertBefore(wrapElement, images02[0]);
images02.forEach(function (element) {
wrapElement.appendChild(element);
});
// '.images01 div' の子要素をspan要素で包む
document.querySelectorAll('.images01 div').forEach(function (element) {
var span = document.createElement('span');
element.childNodes.forEach(function (child) {
span.appendChild(child);
});
element.appendChild(span);
});
// 'section div' の親要素(要するに section)を取り除く
var parents = [];
document.querySelectorAll('section div').forEach(function (element) {
var parent = element.parentNode;
parents.push(parent);
parent.parentNode.insertBefore(element, parent);
});
parents.filter(function (element, i) {
return parents.indexOf(element) === i;
}).forEach(function (element) {
element.parentNode.removeChild(element);
});
最終的にHTMLはこのような感じになります。
<div>
<span><img src="./kaban.jpg" alt="かばん"></span>
</div>
<div>
<span><img src="./serval.jpg" alt="サーバル"></span>
</div>
<div>
<span><img src="./fennec.jpg" alt="フェネック"></span>
</div>
<div>
<span><img src="./common-raccoon.jpg" alt="アライさん"></span>
</div>
<div>
<img src="./kaban.jpg" alt="かばん">
<img src="./serval.jpg" alt="サーバル">
<img src="./fennec.jpg" alt="フェネック">
<img src="./common-raccoon.jpg" alt="アライさん">
</div>
##.is()
要素が指定した状態なのかの真偽値を返します。
以下のようなHTMLがあったとします。
<input id="ppp" class="pppLive" type="text" name="penguins" value="ぺぱぷらいぶ!" disabled>
この要素に対していろいろやってみます。
var $ppp = $('#ppp');
$ppp.is('input'); // true
$ppp.is('div'); // false
$ppp.is('.pppLive'); // true
$ppp.is('.ppp'); // false
$ppp.is('[type="radio"]'); // false
$ppp.is('[name="penguin"]'); // true
$ppp.is(':disabled'); // true
$ppp.is(':checked'); // false
// jQuery で使える特殊セレクタ
$ppp.is(':visible'); // true
$ppp.is(':hidden'); // false
// Element.matches() を使用する(ベンダープレフィックスにも対応させる)
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.webkitMatchesSelector ||
Element.prototype.msMatchesSelector;
}
var getStyle = window.getComputedStyle;
var ppp = document.querySelector('#ppp');
ppp.matches('input'); // true
ppp.matches('div'); // false
ppp.matches('.pppLive'); // true
ppp.matches('.ppp'); // false
ppp.matches('[type="radio"]'); // false
ppp.matches('[name="penguin"]'); // true
ppp.matches(':disabled'); // true
ppp.matches(':checked'); // false
// jQuery で使える特殊セレクタは使用できないので、別の方法を使う
/// :visible の代替
getStyle(ppp).display !== 'none'; // true
/// :hidden の代替
getStyle(ppp).display === 'none'; // false
##.val()
フォーム系要素の値を取得・変更します。
以下のようなフォーム要素があったとします。
<input id="ppp" type="text" name="penguins" value="ぺぱぷらいぶ!">
var $ppp = $('#ppp');
// 値を取得
$ppp.val(); // "ぺぱぷらいぶ!"
// 値を変更
$ppp.val('Penguins Performance Project');
var ppp = document.querySelector('#ppp');
// 値を取得
ppp.value; // "ぺぱぷらいぶ!"
// 値を変更
ppp.value = 'Penguins Performance Project';
##.width(), .height(), .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
要素の幅や高さを取得・変更します。
このメソッドの注意点として、HTML上での見た目の幅・高さと同じ値とは限らないという事です。
要素の状態やメソッドによってさまざまな解釈の違いがあります。
以下のようなCSSが適用されている #contentBox
と #borderBox
いう要素があったとします。
#contentBox,
#borderBox {
width: 100px;
height: 50px;
padding: 10px;
margin: 10px;
padding: 10px;
border: 5px solid #000;
}
#borderBox {
box-sizing: border-box;
}
HTML上の見た目では、#contentBox
は幅が 130px
、高さが 80px
、#borderBox
は幅が 100px
、高さが 50px
な要素になっています。
var
$contentBox = $('#contentBox'),
$borderBox = $('#borderBox');
/* 幅・高さの取得 */
// .width() / .height()
// ブラウザがCSSで解釈している値
$contentBox.width(); // 100
$contentBox.height(); // 50
$borderBox.width(); // 100
$borderBox.height(); // 50
// .innerWidth() / .innerHeight()
// ボーダーを含めない値
$contentBox.innerWidth(); // 120
$contentBox.innerHeight(); // 70
$borderBox.innerWidth(); // 90
$borderBox.innerHeight(); // 40
// .outerWidth() / .outerHeight()
// ボーダーを含めた値
$contentBox.outerWidth(); // 130
$contentBox.outerHeight(); // 80
$borderBox.outerWidth(); // 100
$borderBox.outerHeight(); // 50
/* 幅・高さの指定 */
// .width() / .height()
// ブラウザがCSSで解釈している値
$contentBox.width(70); // HTML上の見た目では 100px になる
$contentBox.height(20); // HTML上の見た目では 50px になる
$borderBox.width(70); // HTML上の見た目では 70px になる
$borderBox.height(20); // HTML上の見た目では 20px になる
// .innerWidth() / .innerHeight()
// ボーダーを含めない値
$contentBox.innerWidth(70); // HTML上の見た目では 80px になる
$contentBox.innerHeight(20); // HTML上の見た目では 30px になる
$borderBox.innerWidth(70); // HTML上の見た目では 80px になる
$borderBox.innerHeight(20); // HTML上の見た目では 30px になる
// .outerWidth() / .outerHeight()
// ボーダーを含めた値
$contentBox.outerWidth(70); // HTML上の見た目では 70px になる
$contentBox.outerHeight(20); // HTML上の見た目では 20px になる
$borderBox.outerWidth(70); // HTML上の見た目では 70px になる
$borderBox.outerHeight(20); // HTML上の見た目では 20px になる
var getStyle = window.getComputedStyle;
function getStyleValue(element, prop) {
return parseFloat(getStyle(element).getPropertyValue(prop)) || 0;
}
var
contentBox = document.querySelector('#contentBox'),
borderBox = document.querySelector('#borderBox');
/* 幅・高さの取得 */
//.width() / .height() の代替処理
getStyleValue(contentBox, 'width'); // 100
getStyleValue(contentBox, 'height'); // 50
getStyleValue(borderBox, 'width'); // 100
getStyleValue(borderBox, 'height'); // 50
// .innerWidth() / .innerHeight() の代替処理
function innerWidth(element) {
var borderWidth = getStyleValue(element, 'border-left-width') + getStyleValue(element, 'border-right-width');
return element.offsetWidth - borderWidth;
}
function innerHeight(element) {
var borderWidth = getStyleValue(element, 'border-top-width') + getStyleValue(element, 'border-bottom-width');
return element.offsetHeight - borderWidth;
}
innerWidth(contentBox); // 120
innerHeight(contentBox); // 70
innerWidth(borderBox); // 90
innerHeight(borderBox); // 40
// .outerWidth() / .outerHeight() の代替処理
contentBox.offsetWidth; // 130
contentBox.offsetHeight; // 80
borderBox.offsetWidth; // 100
borderBox.offsetHeight; // 50
/* 幅・高さの指定 */
//.width() / .height() の代替処理
contentBox.style.width = '70px'; // HTML上の見た目では 100px になる
contentBox.style.height = '20px'; // HTML上の見た目では 50px になる
borderBox.style.width = '70px'; // HTML上の見た目では 70px になる
borderBox.style.height = '20px'; // HTML上の見た目では 20px になる
// .innerWidth() / .innerHeight() の代替処理
function setInnerWidth(element, value) {
var section;
if (getStyle(element).boxSizing === 'border-box') {
section = getStyleValue(element, 'border-left-width') + getStyleValue(element, 'border-right-width');
value = value + section;
} else {
section = getStyleValue(element, 'padding-left') + getStyleValue(element, 'padding-right');
value = value - section;
}
element.style.width = value + 'px';
}
function setInnerHeight(element, value) {
var section;
if (getStyle(element).boxSizing === 'border-box') {
section = getStyleValue(element, 'border-top-width') + getStyleValue(element, 'border-bottom-width');
value = value + section;
} else {
section = getStyleValue(element, 'padding-top') + getStyleValue(element, 'padding-bottom');
value = value - section;
}
element.style.height = value + 'px';
}
setInnerWidth(contentBox, 70); // HTML上の見た目では 80px になる
setInnerHeight(contentBox, 20); // HTML上の見た目では 30px になる
setInnerWidth(borderBox, 70); // HTML上の見た目では 80px になる
setInnerHeight(borderBox, 20); // HTML上の見た目では 30px になる
// .outerWidth() / .outerHeight() の代替処理
function setOuterWidth(element, value) {
var borderWidth, padding;
if (getStyle(element).boxSizing !== 'border-box') {
borderWidth = getStyleValue(element, 'border-left-width') + getStyleValue(element, 'border-right-width');
padding = getStyleValue(element, 'padding-left') + getStyleValue(element, 'padding-right');
value = value - borderWidth - padding;
}
element.style.width = value + 'px';
}
function setOuterHeight(element, value) {
var borderWidth, padding;
if (getStyle(element).boxSizing !== 'border-box') {
borderWidth = getStyleValue(element, 'border-top-width') + getStyleValue(element, 'border-bottom-width');
padding = getStyleValue(element, 'padding-top') + getStyleValue(element, 'padding-bottom');
value = value - borderWidth - padding;
}
element.style.height = value + 'px';
}
setOuterWidth(contentBox, 70); // HTML上の見た目では 70px になる
setOuterHeight(contentBox, 20); // HTML上の見た目では 20px になる
setOuterWidth(borderBox, 70); // HTML上の見た目では 70px になる
setOuterHeight(borderBox, 20); // HTML上の見た目では 20px になる
CSSの box-sizing
を考慮しないといけないので非常にややこしい処理を行っています。めんどくさい……
##.offset(), .position()
ドキュメントルートからみた要素の座標(絶対座標)、親要素から見た要素の座標を取得します。
var $absoluteBlock = $('#absoluteBlock');
// ドキュメントルートからみた #absoluteBlock の座標の取得
var offset = $absoluteBlock.offset();
offset.left; // X座標
offset.top; // Y座標
// 親要素から見た #absoluteBlock の座標の取得
var position = $absoluteBlock.position();
position.left; // X座標
position.top; // Y座標
var absoluteBlock = document.querySelector('#absoluteBlock');
// ドキュメントルートからみた #absoluteBlock の座標の取得
function getOffset(element) {
var rect = element.getClientRects().length > 0 ? element.getBoundingClientRect() : {top: 0, left: 0};
return {
top: rect.top + window.pageYOffset - document.documentElement.clientTop,
left: rect.left + window.pageXOffset - document.documentElement.clientLeft,
};
}
var offset = getOffset(absoluteBlock);
offset.left; // X座標
offset.top; // Y座標
// 親要素から見た #absoluteBlock の座標の取得
function getPosition(element) {
var
offset, offsetParent,
parent = {top: 0, left: 0},
style = window.getComputedStyle(element);
if (style.position === 'fixed') {
offset = element.getBoundingClientRect();
} else {
offset = getOffset(element);
offsetParent = element.offsetParent || document.documentElement;
if (offsetParent.nodeName !== 'HTML') {
parent = getOffset(offsetParent);
}
parent.top += parseFloat(style.borderTopWidth);
parent.left += parseFloat(style.borderLeftWidth);
}
return {
top: offset.top - parent.top - parseFloat(style.marginTop),
left: offset.left - parent.left - parseFloat(style.marginLeft),
};
}
var position = getPosition(absoluteBlock);
position.left; // X座標
position.top; // Y座標
これはちょっとめんどくさいかも……
##.scrollLeft(), .scrollTop()
スクロール位置の取得・設定をします。
// 現在のスクロール位置の取得
$(window).scrollLeft(); // 例えば 0
$(window).scrollTop(); // 例えば 500
// スクロール位置の指定
$(window).scrollLeft(100); // 左から100pxの位置に移動(横スクロールが有効な場合)
$(window).scrollTop(200); // 上から200pxの位置に移動(縦スクロールが有効な場合)
// 現在のスクロール位置の取得
window.pageXOffset; // 例えば 0
window.pageYOffset; // 例えば 500
// スクロール位置の指定
window.scrollTo(100, 200); // 左から100px、上から200pxの位置に移動
##.show(), .hide()
要素を表示・非表示にします。
// #hiddenContent を表示
$('#hiddenContent').show();
// #visibleContent を非表示
$('#visibleContent').hide();
/* 表示するときすべて display: block; でいい場合 */
// #hiddenContent を表示
document.querySelector('#hiddenContent').style.display = 'block';
// #visibleContent を非表示
document.querySelector('#visibleContent').style.display = 'none';
/* 表示するときに要素の display の初期値にしたい場合 */
var defaultDisplay = {DIV: 'block', SPAN: 'inline'};
function getDefaultDisplay(element) {
var nodeName = element.nodeName;
if (!defaultDisplay[nodeName]) {
element = document.body.appendChild(document.createElement(nodeName));
defaultDisplay[nodeName] = window.getComputedStyle(element).display;
document.body.removeChild(element);
}
return defaultDisplay[nodeName];
}
// #hiddenContent を表示
var hiddenContent = document.querySelector('#hiddenContent');
hiddenContent.style.display = getDefaultDisplay(hiddenContent);
##.on(), .off(), .click()等
要素のイベントを追加・削除します。
var $clickHere = $('#clickHere');
// #clickHere にクリックイベントを追加
$clickHere.on('click', function (ev) {
// do something
});
// または
// $clickHere.click(function (ev) {
// // do something
// });
// #clickHere からクリックイベントの削除
$clickHere.off('click');
var clickHere = document.querySelector('#clickHere');
// クリックイベント関数
function clickEvent(ev) {
// do something
};
// #clickHere にクリックイベントを追加
clickHere.addEventListener('click', clickEvent);
// #clickHere からクリックイベントの削除
clickHere.removeEventListener('click', clickEvent);
##.one()
イベントを一度だけ実行します
// #clickHere に一度だけ有効なクリックイベントを追加
$('#clickHere').one('click', function (ev) {
// do something
});
var clickHere = document.querySelector('#clickHere');
// #clickHere に一度だけ有効なクリックイベントを追加
clickHere.addEventListener('click', function clickEvent(ev) {
clickHere.removeEventListener('click', clickEvent);
// do something
});
##.hover()
マウスのホバーイベントを追加します。
// #hoverHere にホバーイベントを追加
$('#hoverHere').hover(function (ev) {
// mouseenter
// do something
}, function (ev) {
// mouseleave
// do something
});
var clickHere = document.querySelector('#clickHere');
// #hoverHere にホバーイベントを追加
clickHere.addEventListener('mouseenter', function (ev) {
// do something
});
clickHere.addEventListener('mouseleave', function (ev) {
// do something
});
mouseover
と mouseout
ではないんですね。
##.toArray()
要素リストを純粋な配列に変換します。
// div要素の取得
var $div = $('div');
$.isArray($div); // false
// 配列に変換する
$div = $div.toArray();
$.isArray($div); // true
// div要素の取得
var div = document.querySelectorAll('div');
Array.isArray(div); // false
// 配列に変換する
div = Array.prototype.slice.call(div);
Array.isArray(div); // true
ECMAScript 2015 なら Array.from()
が使用できます。
// div要素の取得
let div = document.querySelectorAll('div');
Array.isArray(div); // false
// 配列に変換する
div = Array.from(div);
Array.isArray(div); // true
#アニメーション
jQueryはアニメーションが簡単に設定できて便利ですが、CSSでもアニメーションを行えるのでそれで代わりに書いてみようという感じです。
##フェードイン・フェードアウト
ボタンをクリックすると画像がフェードイン・フェードアウトを繰り返す動作をやってみます。
<div id="fadeEffectTarget"><img src="./serval-chan.jpg" width="100" height="200" alt="サーバルちゃん"></div>
<button id="fadeEffect">Click Here</button>
###jQueryを使った例
$('#fadeEffect').click(function () {
$('#fadeEffectTarget').fadeToggle(300);
});
###jQueryを使わない例
#fadeEffectTarget {
transition: opacity 300ms ease;
}
.fadeOut {
opacity: 0;
}
####ただ単にフェードするアニメーションの場合
var target = document.querySelector('#fadeEffectTarget');
document.querySelector('#fadeEffect').addEventListener('click', function () {
target.classList.toggle('fadeOut');
});
####フェードアウト時に display: none; にする必要がある場合
var target = document.querySelector('#fadeEffectTarget');
document.querySelector('#fadeEffect').addEventListener('click', function () {
var transitionEnd = function () {
target.removeEventListener('transitionend', transitionEnd);
target.style.display = 'none';
};
if (target.classList.contains('fadeOut')) {
target.removeEventListener('transitionend', transitionEnd);
target.style.display = 'block';
setTimeout(function () {
target.classList.remove('fadeOut');
});
} else {
target.classList.add('fadeOut');
target.addEventListener('transitionend', transitionEnd);
}
});
他のアニメーションに関しては後日追加する、かも?
#おわりに
DOM関係の操作ってやっぱり面倒ですね。jQueryはやはり便利……
しかし、こういった事を行っていくことで、更にJavaScriptでのDOM関係の操作について理解が深まるのではないかと思います。