最初に必ず書くこと

見出し右端の記号は?

Web Page
Booskanium's Tips.
忘れっぽい落書き人のメモ

無条件で書くようにしています。「/js/__can_i_used.js」にまとめて書いてありますので参照してください。

IEを使わないエコ作戦

ここの落書き人はIEを意識してコーディングするのはやめました。Polyfill、Ponyfill、Transpileを使えばという話もありますが、それで完全に動作するかというテストが加わり、面倒になって辞めました。
落書き人の個人サイトは、以下のJavaScriptを最初に仕込んでIEを撥ね付けています。
この副作用で「/js/__can_i_used.js」の中にES2015以降の構文が書くとエラーになり、以下が実行されないことです。

//IEを使わないエコ作戦(*^_^*)
if (document.uniqueID) {
	alert('このサイトでは「IE」には読解できないモダンな構文を利用しています。\
		\n \nIEを使い続けることは、新しい体験の機会を逸っしています。\
		\nIEはセキュリティ的に危なっかしい機能が実装されたままです。\
		\nインターネット閲覧にはモダンブラウザを使うことを強くお勧めいたします。\
		\n\n\n※2020年10月から強制的にEdgeにリダイレクト!!\
		\n これはMicrosoft自身が、IEで閲覧するとEdgeに強制的にリダイレクトするサービスを開始しました。\
		\n このサービスは登録制です。TwitterやYoutubeはすでにリダイレクトされます。\
		\n Microsoft自身のサービスもすでにEdgeにリダイレクトされるケースがあります。\
		\n これは未だにIE対応が求められる日本にとっては朗報です。\
		\n このマイクロソフトのサービスにサイトドメインを登録してしましょう。\
		\n\n\n※いよいよ2022年6月16日にIEサポート終了\
		\n どうやらこれ以降はIEを開こうとするとEdgeに強制的に切り替わるようです。\
		\n ユーザーとWeb系技術者にとっては朗報です。');
	window.location.href = '/gotomodern.html';
}

Can I use

訪問しているブラウザの機能チェックです。そろそろIEに対する判定は除外する予定です。
この判定の必要性ですが、Web APIなどを使用すると未だにブラウザによって動作が異なる場面があります。

var __use = (function(){
	return {
		ltIE6:typeof window.addEventListener == "undefined" && typeof document.documentElement.style.maxHeight == "undefined",
		ltIE7:typeof window.addEventListener == "undefined" && typeof document.querySelectorAll == "undefined",
		ltIE8:typeof window.addEventListener == "undefined" && typeof document.getElementsByClassName == "undefined",
		ltIE9:document.uniqueID && typeof window.matchMedia == "undefined",
		gtIE10:document.uniqueID && window.matchMedia,
		Trident:document.uniqueID,
		isMSIE:/*@cc_on!@*/false,
		isMSIE11:(document.documentMode === 11),
		Edge:(navigator.userAgent.indexOf("Edge") != -1),
		Gecko:'MozAppearance' in document.documentElement.style,
		Presto:window.opera,
		Blink:window.chrome,
		Webkit:typeof window.chrome == "undefined" && 'WebkitAppearance' in document.documentElement.style,
		Touch:typeof document.ontouchstart != "undefined",
		Mobile:(typeof window.orientation != "undefined") || (navigator.userAgent.indexOf("Windows Phone") != -1),
		ltAd4_4:typeof window.orientation != "undefined" && typeof(EventSource) == "undefined",
		Pointer:window.navigator.pointerEnabled,
		MSPoniter:window.navigator.msPointerEnabled,
		hasTapEvent: false,
		browser:(
			(function() {
				if(navigator.userAgent.indexOf('Edge') != -1) {
					return 'Edge';
				} else if(navigator.userAgent.indexOf('Vivaldi') != -1) {
					return 'Vivaldi';		//現在のVivaldiはChrome偽装しているので判定不能、Vivaldiの癖が回避出来なくて困る
				} else if(navigator.userAgent.indexOf('Chrome') != -1) {
					return 'Chrome';
				} else if(navigator.userAgent.indexOf('Safari') != -1) {
					return 'Safari';
				} else if(navigator.userAgent.indexOf('Waterfox') != -1) {
					return 'Waterfox';
				} else if(navigator.userAgent.indexOf('Firefox') != -1) {
					return 'Firefox';
				} else {
					return 'unknown';
				}
			}())
		),
		os:(		//癖のあるiPhoneが判定できればなんとかなる?、どっちにしろOS判定は困難
			(function() {
				if(navigator.userAgent.indexOf('iPhone') != -1) {
					return 'iPhone';		//iPhoneのiOSのWebkitは曲者なので判定が必要
				} else if(navigator.userAgent.indexOf('Mac') != -1) {
					return 'Mac';
				} else if(navigator.userAgent.indexOf('Android') != -1) {
					return 'Android';
				} else {
					return 'unknown';
				}
			}())
		)
		/*
		 ブランド情報を取得の記述を有効にするとIEがasyncが理解できずにエラーになるので時期尚早
		 そしてブランド情報に対応しているのはまだChromium系のみ
		*/
		/*
		),
		//User-Agent Client Hints 
		ua_ch:(
			(function() {
				if (window.navigator.userAgentData) {
					// ブランド情報を取得
					return navigator.userAgentData;
				} else {
					return undefined;
				}
			}())
		),
		entropy:(
			(async function() {
				if (navigator.userAgentData) {
					let uaData = navigator.userAgentData;
  					// getHighEntropyValues関数には、
					// 取得したい情報を配列の引数で渡す必要があります。
					const ent = await uaData.getHighEntropyValues(
				    [
    				  "platform",
    				  "platformVersion",
    				  "architecture",
    				  "model",
    				  "uaFullVersion"
    				]);
					return ent;
				} else {
					return undefined;
				}
			}())
		)
		*/
	}
})();

//タッチイベント実装検査 スワイプなどが使えるかなどの判断で使う
window.addEventListener('load', function(){
	//タッチイベントの判定
	var iframe = document.createElement('iframe');
	document.body.appendChild(iframe);
	__use.hasTapEvent = ('ontouchstart' in iframe.contentWindow);
	iframe.remove();
	//なんちゃって偽造ブラウザ判定
	if (window.AudioContext) {
	} else {
		if (__use.browser == 'Firefox') {
			//Tor BrowserがFirefoxを偽装しているっちゃ
			__use.browser = 'TorBrowser';
		}
	}
	if (__use.browser == 'Chrome') {
		try {
			__use.tmpAudio = new Audio();
			delete __use.tmpAudio;
		} catch (e) {
			//偽装するならChromeを完全模写してくれないと困るぞ!
			__use.browser = 'Vivaldi';
		}
	}
}, false);

//URL引数, URLハッシュを取得
var __url =  {
	//URL引数を取得
	args : (function() {
		//URL引数取得
		var a = new Object();
		a.deb = false;
		var params = location.search.substring(1).split('&');
		for (var i = 0; i < params.length; i++) {
			var keyval = params[i].split('=');
			if (keyval.length < 2) {
				if (keyval[0] == 'deb') {
					a.deb = true;	//デバックモード指定
				} else {
					a[keyval[0]] = ''; 	//値無し引数
				}
			} else {
				a[keyval[0]] = keyval[1];
			}
		}
		return a;
	})(),
	//URLのフラグメント識別子(#以後の文字列)
	protocol : location.protocol,
	host : location.host,
	pathname : location.pathname,
	hash : location.hash,
	asmSearch : function() {
		//if (this.args.length > 0) {
			var search = '';
			for (var k in this.args) {
				if (k == '') {
					//nop
				} else if (k == 'deb' && this.args[k] == false) {
					//nop
				} else {
					search += (search == '') ? '?' : '&';
					search += (this.args[k] == '') ? k : k + '=' + this.args[k];
				}
			}
			return search;
		//} else {
		//	return '';
		//}
	}
}

利用例:

if ('data' in __url.args) {		//URL引数dataが指定されていたら
	data = __url.args.data;		//URL引数dataの値を参照
}