このブログを作る際に、noscriptタグを使用するのに少してこずったので、備忘録として残しておきます。
ちなみに、このブログは Nuxt v2
で作ってあります。
HTML内でnoscriptタグを使用すると、JavaScriptが無効の時のみ表示される部分を作ることができます。
具体的には下のようにできます。
...
<noscript>
JavaScriptを有効にしてください。
</noscript>
...
こうすると、JSが無効の時のみ、警告を出すことができます。
まあいないと思うけど、
というような人たちに、
「このサイトはJSないと正しく表示できないよ!」
と優しく教えてあげることができます。
まあいないと思うけど。
これは極端な例ですが、実際、ユーザーフレンドリーな設計は大事ですよね。
ところが、これをNuxtとかの仮想DOM系のフレームワークで使おうとすると、うまくいかないことがあります。
noscript内はJSで読まれないから、実際のDOMと仮想DOMが噛み合わなくなるのかな。(詳細は知りません。)
このサイトはSSGで、生成時にサーバー側で処理できるので、その時は無視せず、クライアント側でJS無効の場合のみ表示したい。
noscript内でコンポーネントを使いたい。(わがまま)
そこで、CSSで制御しようと考えました。
普段は display: none;
で隠しておき、noscript内にstyleタグを入れて、 display: inherit;
で元に戻してやりましょう。
以下はNuxt2での対処法です。他のフレームワークに応用する際は、適宜読みかえてください。
上のドキュメントによると、プロジェクトのルートディレクトリ(srcDirを設定してる場合はそのディレクトリ)に以下の内容で app.html
を設置すると、Viewをコントロールできるそうです。
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
これを以下のように変更します。
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
<!-- 追記ここから -->
<style>.noscript { display: none; }</style>
<noscript><style>.noscript { display: inherit; } .withscript { display: none; }</style></noscript>
<!-- 追記ここまで -->
{{ APP }}
</body>
</html>
追記した2行で、JSの有効or無効で表示を切りかえられるようになりました。
JS無効時にのみ表示したい要素には、 .noscript
というclassを追加します。
逆に、JS有効時のみ表示したい要素には、 .withscript
を追加します。
<div class="withscript">
JSは有効です。
<SomeComponent>js enabled</SomeComponent>
</div>
<div class="noscript">
JSは無効です。
<SomeComponent>js disabled</SomeComponent>
</div>
こんな感じで、この方法なら、中にコンポーネントがいる要素でもいけました。
実際に、このブログの検索画面に使われているので、JS無効化して試してみてください。