【初心者向け】JavaScript(jQuery)のレガシーブラウザ対応について

DDS匠ブログ
Tips
Web

WEB

【初心者向け】JavaScript(jQuery)のレガシーブラウザ対応について

【初心者向け】JavaScript(jQuery)のレガシーブラウザ対応について

CSS3やJavaScriptライブラリ(フレームワーク)は、スマートフォンの進化と共に徐々に増え、今では何らかを使用して制作することが当たり前になっています。制作するページがPC・スマートフォンなどのモダンブラウザ(*1)だけを考慮するなら問題ないのですが、サイトの仕様によりレガシーブラウザ(*2)にも対応しなければいけないこともいまだに珍しくはありません。私もこれまでCSSやJavaScriptについて、IE(Internet Explorer)などのレガシーブラウザ対応を行ってきました。今やレアケースの対応かもしれませんが、よくある対応ポイントを今回はいくつかピックアップしてみたいと思います。

(*1)…Web標準への準拠が進んでいるブラウザ。最新バージョン
(*2)…Web標準への準拠が進んでいないブラウザ

IE環境でのES6

ES6(*3)と呼ばれる記述方法は、簡潔で便利な書き方になりますが、IE11以下の環境で使用できないものが多くあります。そのため、ES5(*4)の書き方にトランスパイル(*5)しなければなりません。このようなケースになる原因は、サイト仕様の見落としによりモダンブラウザで検証を行い、レガシーブラウザで使用できないことに気づかないことです。
ES5に変換する際にBabel(*6)のようなJavaScriptトランスパイラが使用できれば簡単なのですが、手動で書き直すのは多少手間がかかります。そうならないために、気をつけるポイントのいくつかを見ていきましょう。

(*3)…JavaScriptの標準規格のバージョン「ECMAScript 6th Edition」の略称。正式名称は「ES2015」
(*4)…2015年以前のJavaScript標準規格のバージョン「ECMAScript 5th Edition」の略称
(*5)…あるプログラミング言語で書かれたものを、別の言語(バージョン)に変換すること。
(*6)…「ES6」を「ES5」に変換できるツール

変数宣言

ES6
let
const
	
ES5
var

ES6の「let」は再定義が不可、「const」は再代入や再定義が不可で、かつ両方ともブロックスコープ(*7)として扱うことができます。しかし、残念ながらIE10以下ではエラー(※)になってしまいます。その場合は「var」に変更することになりますが、変数名がグローバル変数(*8)などと被っている可能性があるので、意図しない箇所で参照データが書き変わらないよう必要に応じてユニークな変数名に変更しなければいけません。

※JavaScriptのエラーは、ブラウザの「開発者ツール」の「console」に表示されます。
「開発者ツール」の表示方法は、ブラウザを開いてから、

  • Windows : 「F12」
  • Mac OS :「command」+「option」+「i」

などで表示できます。

(*7)…「{ }」で囲まれたブロック毎に作られるスコープのこと。ブロック外側からのアクセス不可、内側は可。
(*8)…一番上の階層で定義された変数で、どこでも呼び出すことができる。反対に、関数(ブロック)内でのみ使用できるものはローカル変数。

アロー関数

ES6
let aaa = () => {〜}
ES5
var aaa = function() {〜}

アロー関数とは、見た目の通りアロー(矢)の形をした「=>」で定義する関数です。この場合は「function」にそのまま変更することができますが、注意する点は前述の変数名と「this」の部分です。アロー関数内の「this」は、同階層から順次上の階層まで同一オブジェクト内を検索し適用しますが、単純に「function」に変更しただけだと構成によっては同じ動きをせずにスコープが変わってしまう可能性があるので注意しましょう。

class構文

ES6
class classTest {
	constructor(num1,num2){
		this.num1 = num1;
		this.num2 = num2
	}
	calcTest(){
		return Math.round(this.num1 * this.num2);
	}
}

let aaa = new classTest(2,3);

console.log(aaa.calcTest());
ES5
function ClassTest (num1,num2){
	this.num1 = num1;
	this.num2 = num2;
}

ClassTest.prototype = {
	calcTest: function(){
		return Math.round(this.num1 * this.num2);
	}
}

var aaa = new ClassTest(2,3);

console.log(aaa.calcTest());

ES5への変換は、「prototype」を使用した場合の一例になります。ES6のclass構文は、コンストラクタとメソッドをひとつのパッケージとしてまとめることができます。またこれをベースに一部だけ変更して再利用する(継承)こともできます。同じような形を残し変換することを考えた場合、右上部の書き方になります。コンストラクタ部分を「function」で定義し、メソッド部分を「prototype」を使用して定義します。大抵は、このパターンで行けると思います。

jQuery関数と間違えやすいもの

jQueryライブラリは、JavaScriptを拡張するものとして多くのサイトで使用されています。その中で、いくつかJavaScript関数と混同してしまうものが存在します。jQuery関数として処理を行えれば問題なかったのかもしれませんが、JavaScript関数として認識された場合はIE11以下で処理できなくなります。このパターンの悪いところは、jQueryを使用していると思い込んで見逃しがちになってしまうことです。
下記3つについては、レガシーブラウザ(IE)でエラーや注意が表示されたものになります。

append

JQuery
$('#aaa').append ('<p class="mt-4">テキスト</p>');
JavaScript
var elm = document.getElementById('aaa');
var addElm = document.createElement('p');

addElm.append('テキスト');

elm.append(addElm);
代替案
var elm = document.getElementById('aaa');
elm.insertAdjacentHTML('beforeEnd', '<p class="mt-4">テキスト</p>');

「append」は、要素内の最後に新しい要素を付け加えたい場合に使用します。JavaScriptでjQueryの動きと同じようにする場合、少々記述量が増えてしまっていますが、仮に上記のような使い方をしていた場合は、残念ながらエラーとなってしまいます。(例がいまいちですがご了承ください…)
その場合の代替案として、「insertAdjacentHTML」も同じように使うことができます。上記の「beforeEnd」の部分には、「insertAdjacentHTML」のオプション(※)を設定します。JavaScriptで作成する場合、初めからこちらを使用した方が簡潔ですね。

※オプションの詳細はリファレンスサイト(MDN)を参照
https://developer.mozilla.org/ja/docs/Web/API/Element/insertAdjacentHTML

prepend

JQuery
$('#aaa').prepend ('<p class="mt-4">テキスト</p>');
JavaScript
var elm = document.getElementById('aaa');
var addElm = document.createElement('p');

addElm.append('テキスト');

elm.prepend(addElm);
代替案
var elm = document.getElementById('aaa');
elm.insertAdjacentHTML('afterBegin', '<p class="mt-4">テキストu</p>');

「prepend」は、要素内の先頭に新しい要素を付け加えたい場合に使用します。こちらも前述と同じように、JavaScriptではエラーになってしまいます。
この場合の代替案も「insertAdjacentHTML」を使い、オプションを「afterBegin」で設定すれば同じことができます。

※オプションの詳細はリファレンスサイト(MDN)を参照
https://developer.mozilla.org/ja/docs/Web/API/Element/insertAdjacentHTML

find

JQuery
$(‘#aaa’).find ('.bbb');
JavaScript
var myFruit = 'apple';
var fruits = ['orange', 'strawberry', 'melon', 'apple', 'banana'];

var result = fruits.find(function(item){
	return item === myFruit;
});
代替案
var myFruit = 'apple'
var fruits = ['orange', 'strawberry', 'melon', 'apple', 'banana']

var result = fruits.filter(function(item){
	return item === myFruit;
});

「find」もJavaScriptで使用の場合、IEでは認識されません。jQueryでは子要素に対し該当する要素全てを抽出しますが、JavaScriptでは配列内を検索し最初に該当した要素の値を抽出します。jQuery関数として使用していれば問題ないと思いますが、JavaScript関数として使用していた場合、こちらもエラーになってしまいます。代替案は「filter」を使うことですが、「result」の内容(形式)が違ってきますので、扱う際は注意が必要です。

まとめ

今回は、JavaScriptでのレガシーブラウザ対応の一部をご紹介しましたが、いかがでしたでしょうか。IE系で動かなくなるものについては、こちらで紹介した以外にもいくつかあります。このような事象に遭遇した場合は、まずはエラーの起きている箇所を特定し対策を行います。開発者ツールなどで調査し新たな方法を考えることを繰り返し行うことによって、理解や対応力が自然と身に付いてくると思います。悩んでいる時には辛い作業になりますが、よい経験として後々役立つと思うので、さまざまなことを解決できる力になるようお互い頑張っていきましょう。


デザイン&デベロップメントスタジオについて「もっと詳しく知りたい!」という方は、Wantedlyのページにより詳しい情報が載っていますので、ぜひ覗いてみてください。また、直接社員と話せる『カジュアル面談』のお申し込みも可能です。お気軽にご連絡ください。

株式会社デジタルスケープの会社情報 - Wantedly

株式会社デジタルスケープ デザイン&デベロップメントスタジオ 高杉 充
株式会社デジタルスケープ
デザイン&デベロップメントスタジオ
高杉 充

2005年よりWEB業界に入り、未経験ながらOJTで1年ほど数社のサイト更新を経験した後、以降はグローバルメーカーやWEB証券会社のサイト運用など大手から中小企業まで様々な案件にWEBコーダー・フロントエンドエンジニアとして携わる。現在は、フロントエンドエンジニア・ディレクターとして、サイトリニューアルやお客様先常駐案件などの提案から制作・運用までを担当。
コミュニケーションを通して信頼関係を構築し、安心して働ける環境でメンバーと共に成長することが何よりの喜びです。