[JS] JavaScriptからメディアクエリの実装を判定

var mediaQueriesSupported = (function() {
	var supported = false;
	var styleSheet = document.styleSheets[0];
	var targetRuleIndex = (styleSheet.cssRules || styleSheet.rules).length;

	if ( styleSheet.insertRule ) {
		styleSheet.insertRule(
			'@media all and (min-width: 1px) { .mediaquery-testtarget { position: absolute; } }',
			targetRuleIndex
		);
	} else {
		return supported;
	}

	var d = document.createElement( 'div' );
	d.className = 'mediaquery-testtarget';
	document.body.appendChild( d );

	var style = d.currentStyle || document.defaultView.getComputedStyle( d, '' );
	supported = style.position === 'absolute';
	document.body.removeChild( d );

	return supported;
})();

メディアクエリが機能するか実際に試してその結果から判定。StyleSheetオブジェクトがinsertRuleメソッドを持たない場合(IE8以下)は、もうそこで非対応とみなしています。処理の都合上、DOM構築完了以後に記述する必要があります。

window.matchMedia


JavaScriptからメディアクエリを扱うための機能としてwindow.matchMediaというものがありますが、これの判定に関しては下記のような簡易なもので十分でないかと思います。

var matchMediaSupported = !!window.matchMedia;

matchMediaという名前のグローバル変数がどこかの何かによって定義されるのを想定する場合とか、もっとちゃんと判定したいなら実際に動かして機能をテストします。この判定によって最初のメディアクエリも対応していると見なして良いんじゃないかって気がしますが、実際はメディアクエリに対応しているけどwindow.matchMediaは対応していないブラウザが存在するので難しいところです。IE9とか。

またwindow.matchMediaが返すMediaQueryListオブジェクトが実装によってaddListenerメソッドを持ってたり持ってなかったりもします。Safari 5(iOS 4)とかのレアケースではありますが、ブレークポイントをトリガーに処理をハンドリングしたいとかの場合は気に留めておくと良いかもしれません。簡易な実装の判定は下記のようになるでしょうか。

var matchMediaAddListenerSupported = !!(window.matchMedia && window.matchMedia( 'all' ).addListener);

なおwindow.matchMediaをPolyfillする下記のようなライブラリもあり、MediaQueryList.addListenerのサポートも拡張で可能にしてくれています。

matchMedia.js


コメントを残す

メールアドレスが公開されることはありません。


五 + 4 =

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>