無条件で書くようにしています。「/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の値を参照
}