最近のWebではどんどんjQueryが使われなくなり。ネイティブのJavascriptのみが使われているサイトが多くなってきたらしいです。理由はページの読み込み速度の向上を狙ってとのこと。
自分も今使っているjQueryのコードをネイティブのJavascriptに書き換えてみよう、という事でチャレンジしてみました。
要素の取得はjQueryでは「$(‘~~’)」で色々な要素を取得できますね。
//ID名で取得
$('#id-name');
//クラス名で取得
$('.class-name');
//タグ名で取得
$('tag-name');
//ID名で取得
document.getElementById('element');
//クラス名で取得
document.getElementsByClassName('element');
//タグ名で取得
document.getElementsByTagName('element');
ネイティブのJavascriptだと文字が多くなる上にID名、クラス名、タグ名などそれぞれ違う物を使い分ける必要があります。覚えてしまえば全然平気です。
アニメーションは主にCSSで書きます。そしてjQueryの「addClass()」や「removeClass()」、「toggleClass()」でクラス名を追加したり削除したりして、アニメーションイベントの制御を行っていました。
//クラス名の追加
$('#element').addClass('active');
//クラス名の削除
$('#element').removeClass('active');
//トグル
$('#element').toggleClass('active');
//要素が指定したクラス名を持っているか
$('#element').hasClass('active');
//クラス名の追加
document.getElementById('element').classList.add('active');
//クラス名の削除
document.getElementById('element').classList.remove('active');
//トグル
document.getElementById('element').classList.toggle('active');
//要素が指定したクラス名を持っているか
document.getElementById('element').classList.contains('active');
classListで要素のクラスを操作することができます。これも簡単に置き換えられますね。
ある位置までスクロールするとヘッダーを固定するなど、スクロール位置もイベント制御によく使います。
//要素の上部の位置を取得
$('#id-name').offset().top
//要素の座標を取得
var rect = document.getElementById('id-name').getBoundingClientRect();
//スクロール量を取得
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
//スクロール量も考慮した要素の上部の位置
rect.top + scrollTop
jQueryだと1行なのにネイティブだと3行になってしまいました。
まず「getBoundingClientRect()」で要素の上下左右の位置を取得できます。しかし、それだけだとスクロールされた場合に座標がズレてしまう問題があります。なので、「window.pageYOffset || document.documentElement.scrollTop」でスクロール量を取得して、要素の座標に足してやる必要があります。
JavascriptでCSSのプロパティを操作することもままあります。
//高さを80pxに指定
$('#id-name').css('height', '80px');
//高さを80pxに指定
document.getElementById('id-name').style.height = '80px';
ネイティブのJavascriptでは「style」でCSSプロパティを操作できます。プロパティ名で気をつけなければいけないのは「margin-top」など、「-(ハイフン)」があるプロパティ名はハイフンなしで「marginTop」と、キャメルケースで書かないといけません。
jQueryだとプロパティ名と値を引数で指定しましたが、ネイティブでは代入する形になり少し書き方が変わります。
ボタンをクリックした時の処理など、ネイティブのJavascriptではイベントリスナーに登録して処理を指定します。
//クリック時の処理
$('#id-name').on('click', function() {
//ここに処理をかきます。
});
//クリック時の処理
document.getElementById('id-name').addEventListener('click', function(){
//ここに処理をかきます。
});
イベントの登録に「addEventListener()」を使います。1番目の引数に’click’などイベントタイプを指定して、2番目の引数に関数で処理をかきます。
最後はページトップボタンです。
jQueryだと「animate()」関数で簡単にアニメーションしてページトップへのスクロールが可能ですが、ネイティブのJavascriptだとややこしくなります。
$('#topbtn).click(function() {
$('body,html').animate({
scrollTop: 0
}, 500);
return false;
});
//イベントリスナーへの登録
pageTop.addEventListener('click', function() {
//現在のスクロール位置を取得
var x = document.body.scrollLeft || document.documentElement.scrollLeft;
var y = document.body.scrollTop || document.documentElement.scrollTop;
//スクロール先の座標を指定
var toX = x;
var toY = 0;
// スクロール位置を toPageTop() 関数へ渡して呼び出す
scrollToAnimation(x, y, toX, toY, pageTopOptions.scrollSpeed, 'up');
return false;
});
/*--------------------------------------------------------
* 指定した座標へスクロールアニメーション Native
*-------------------------------------------------------- */
function scrollToAnimation(x, y, toX, toY, scrollSpeed, direction){
if (direction === 'up') { //上へスクロールする場合
if (y > toY) {
var scTop = Math.floor(y - (y / (scrollSpeed * 2))); //Y座標を計算
window.scrollTo(x, scTop); //計算したY座標までスクロール
scrollTimer = setTimeout(function(){scrollToAnimation(x, scTop, toX, toY, scrollSpeed, 'up')}, scrollSpeed);
// ↑ y の値が1以下になるまで 少しの数値分だけスクロールアップするのを
// scrollSpeed の設定時間ごとに繰り返す
} else {
clearTimeout(scrollTimer);
// ↑ y の値が1以下になったらタイマーを止めて数値を引くのをやめる
window.scrollTo(x, toY);
}
} else if(direction === 'down') { //下へスクロールする場合
if (y < toY) {
var scTop = Math.floor(y + (y / (scrollSpeed * 2) + 1));
if(scTop == 0) scTop++;
window.scrollTo(x, scTop);
scrollTimer = setTimeout(function(){scrollToAnimation(x, scTop, toX, toY, scrollSpeed, 'down')}, scrollSpeed);
// ↑ y の値が1以下になるまで 少しの数値分だけスクロールアップするのを
// scrollSpeed の設定時間ごとに繰り返す
} else {
clearTimeout(scrollTimer);
// ↑ y の値が1以下になったらタイマーを止めて数値を引くのをやめる
window.scrollTo(x, toY);
}
}
}
ネイティブのJavascriptだと大量に記述が増えてしまいました。ネイティブではアニメーションするための関数がないようなのでアニメーションのJavascriptライブラリを使用するかこのように処理を書いてあげなければいけません。
アニメーションに関して、そのほか「slide」や「fade」といったjQueryの関数などもネイティブで書くと複雑になります。
ネイティブのJavascriptへの対応作業をしていて、書き慣れているというのはもちろんあるけれど、jQueryは直感的に書くことができてネイティブのコードに比べて親しみやすいです。あとIE9など古いブラウザへ対応する場合ネイティブだと動かない場合があるので注意が必要です。
今後jQueryを扱えない案件もあるかもしれないし、読み込み速度の向上を考えるとjQueryなしでも書けるようにしておかないといけませんね。