3

2 つの質問があります。

まず、シナリオ:

NOSCRIPT のモバイル ブラウザ サポートに関していくつかの奇妙な問題が発生したため、JS を「検出」するための代替ソリューションを考案する必要があります。ソリューション ロジックは、ページに 2 つの DIV を配置することです。1 つは、JS がなく、デフォルトで表示されていることを示すエラーです。JS がある場合は、前の CSS をオーバーライドしてエラーを非表示にし、代わりにコンテンツを表示する新しい STYLE ブロックを HEAD に追加します。

サンプル HTML:

<div id="div1">div 1 (should be shown if JS enabled)</div>
<div id="div2">div 2 (should be hidden if JS enabled)</div>

これは私が始めたJSです:

  var styleNode = document.createElement('style');
  styleNode.setAttribute("type", "text/css");
  styleNode.innerHTML = "#div1 {display: block;} #div2 {display: none;}";
  headTag.appendChild(styleNode);

しかし、私は問題を抱えていました。DOM に配置する前に、作成された要素に innerHTML を挿入しようとすると、IE で発生する可能性のあるセキュリティ上の問題について、いくつかのグーグル検索が行われました。

http://karma.nucleuscms.org/item/101

そのため、スクリプトを次のように変更しました。

  var styleNode = document.createElement('style');
  styleNode.setAttribute("type", "text/css");
  var headTag = document.getElementsByTagName("head")[0];
  headTag.appendChild(styleNode);
  var aStyleTags = headTag.getElementsByTagName("style");
  var justAddedStyleTag = aStyleTags[aStyleTags.length-1];
  justAddedStyleTag.innerHTML = "#div1 {display: block;} #div2 {display: none;}";

質問 1 : IE の問題に対する有効な回避策ですか? より効率的な解決策はありますか?

質問 2 : 調整を行ってもスクリプトが IE で動作しません。Firefox では正常に動作しますが、IE 7 では「不明なランタイム エラー」が発生します。

このコードのサンプルが JSBIN にあります。

http://jsbin.com/ucesi4/4

IEで何が起こっているか知っている人はいますか?

アップデート:

私はグーグル経由でこのリンクに出くわしました。最後のコメントに注意してください。

http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx

とはいえ、XHTML に厳密に準拠するには、すべてのスタイル ルールを HEAD に配置する必要があります。innerHTML を使用して HEAD 要素または STYLE 要素に直接挿入することはできないため、これを行うのも少し難しい場合があります。(これらのタグは両方とも読み取り専用です。)

えっ!真実?FireFox は寛容すぎるだけですか? それとも、これは非常に奇妙な IE の癖ですか?

更新 2:

ここで解決しようとしていることについて、もう少し背景を説明します。私たちはモバイル デバイスを扱っていますが、一部の時代遅れのデバイスは、a) NOSCRIPT をサポートしておらず、b) 遅い JS エンジンを使用しています。

それらは NOSCRIPT をサポートしていないため、デフォルトでエラーを表示し、JS がある場合はエラーを非表示にし、適切なコンテンツを表示します。これらの JS エンジンが遅いため、DIV の表示/非表示の「ちらつき」が見られます。これは、DIV がレンダリングされる前に CSS をロードするため、これを処理するために提案されたソリューションでした。

無効に見えるため、解決策は、これらの古いデバイスでこのメソッドを使用することです (IE でなくても機能するように見えるため)。その後、他のすべての適切なブラウザーは提案どおりに動作します...各 DIV が DOM にロードされた後、インライン JS を介して DISPLAY CSS プロパティを更新するだけです。

とはいえ、この問題が IE のバグなのか、それとも STYLE を読み取り専用要素にすることで IE が実際に適切な標準に準拠しているのかについて、私はまだ興味があります。

4

3 に答える 3

6

IE では以下を使用できますstyle.styleSheet.cssText

var style = document.createElement('style');
style.type = 'text/css';

if (style.styleSheet) { // IE
    style.styleSheet.cssText = css;
} else {
    style.appendChild(document.createTextNode(css));
}

document.getElementsByTagName('head')[0].appendChild(style);

ここでこれを試してください:http://jsfiddle.net/QqF77/

この質問に対する回答を参照してください: How to create a <style> tag with Javascript

于 2011-09-04T11:43:29.813 に答える
1

使用しないinnerHTMLで、使用するdocument.createTextNode()と、あなたの人生は無限に良くなります ;)

var styleNode = document.createElement('style');
styleNode.setAttribute("type", "text/css");
var textNode = document.createTextNode("#div1 {display: block;} #div2 {display: none;}");
styleNode.appendChild(textNode);
headTag.appendChild(styleNode);

編集:

この解決策はあなたにはうまくいかないようですので、私はそれを放棄します. 代わりに、スタイルが既に定義されていて、利用可能な場合は javascript を介してスタイルを無効/有効にするソリューションを使用してください。

次の方法で実行できます。

<head>
<style>
.jsenabled #div2, #div1 { display: none;}
.jsenabled #div1, #div2 { display: block;}
</style>
<script>
//i know you don't use jQuery, but the solution should still be valid as a concept
//bind to DOM-ready, then set the class jsenabled on the body tag
$(function() {
 $(document.body).addClass('jsenabled');
});
</script>
</head>
<body>
<div id="div1">div 1 (should be shown if JS enabled)</div>
<div id="div2">div 2 (should be hidden if JS enabled)</div>
</body>

編集2:

DOM の準備が整う前にそれを行う必要がある場合は、次のようなちょっと醜いことを行うことができます。

<head>
<style>
#div2, .show { display: block;}
#div1, .hide { display: none;}
</style>
</head>
<body>
<div class="hide">
<script>document.write('</div><div id="div1">');</script>
   div 1 (should be shown if JS enabled)
</div>
<script>document.write('<div class="hide">');</script>
<div id="div2">div 2 (should be hidden if JS enabled)</div>
<script>document.write('</div>');</script>
</body>

または、物事を単純にするために、次のようにすることもできます

<head>
<script>document.write('<style>#div1 {display: block;} #div2 {display: none;}</style>');
</head>
<body>
<div id="div1">div 1 (should be shown if JS enabled)</div>
<div id="div2">div 2 (should be hidden if JS enabled)</div>
</body>
于 2011-03-08T08:20:00.367 に答える
0

ベスト プラクティスは、CSS のすべての <link を <head に配置し、ほとんどの <script を <body の最後に配置することです (ただし、できるだけ早く実行する必要がある <script の短いフラグメントは <head に配置する必要があります)。標準とブラウザーの両方でばかげたことを行うことができますが、それが受け入れられるからといって、それが良い考えであるとは限りません。

Style ノードを作成して DOM を操作するすべての厳密な役割を実行するのではなく (問題が発生する可能性が高くなるだけです)、はるかに単純なソリューションをお勧めします。毎回その場で何かを作成するのではなく、事前にドキュメント (およびスタイル シート?) にできるだけ多くのハード コードを作成します。大まかな例を次に示します。

<body ...
...
<div id="warning" style="display: block;">
JS is required for this site, but isn't available ...
</div>
<div id="message" style="display: none;">
JS is available
</div>
...

<script ...
var warningEl = document.getElementById('warning');
warningEl.style.display = 'none';
var messageEl = document.getElementById('message');
messageEl.style.display = 'block';
</script ...

ほとんどの場合、これで問題なく動作するはずです (最初に試みたブラウザよりも多くのブラウザで動作することは間違いありません)。ただし、ページが最初にユーザーに表示される前に何らかの方法DOM を変更しようとしても、動作することが保証されていません (つまり、あなたの方法も上記の例も、すべての場合に常に動作するわけではありません)。JavaScript を早く実行するほど、DOM 操作 (getElementById を含む) が失敗する可能性が高くなります。そして、後で Javascript を実行するほど、ユーザーはディスプレイの知覚可能な「ちらつき」に気付く可能性が高くなります。したがって、幅広い互換性と目立ったちらつきの間のトレードオフの選択が提示されます。

Javascript を実行する前に、DOM が完全に準備できることが保証されるまで待つことができます (jQuery では「準備完了」、または addEventListener 'domcontextloaded' または addEventListener 'load' でさえ)。これは、すべての場合に正しく機能することが保証されています。しかし、多くの場合、ちらつきます (おそらくかなりひどく)。

私が知っている唯一の方法 (しかし、他の誰かがもっと知っていることを願っています:-) ちらつきの可能性を完全に回避する唯一の方法は、 <headに window.location を変更するが他に何もしない Javascript のフラグメントを入れることです。(DOM への参照はありません。これは、通常、コードのどこかに「ドキュメント」という単語があることで明らかになります。) JS が使用可能な場合の最終的な効果は、ユーザーに何かが表示される前に、別のページが即座にリロードされることです。最初のページには警告を含めることができ、新しいページには警告のない実際のものを含めることができます。

ただし、この方法にもいくつかの欠点があります。まず、二重ダウンロードは余分な帯域幅を必要とし、ユーザーの可視性を少し遅らせます。これは、一般的なデスクトップでは問題になりません。ただし、ハンドヘルドでは受け入れられない場合があります。そして第二に、それは SEO に大混乱を引き起こします。2 番目のページ (非表示で、最初のページからのみアクセスする必要がある) は Webdex で個別に表示されるため、ユーザーは簡単に直接アクセスできます (「正規」および/またはを巧妙に使用してこれを「修正」できる場合があります)。 「メタ...ロボット」)。また、最初のページのコンテンツが警告メッセージのみの場合、SERP が急激に低下する可能性があります。

于 2013-06-12T16:26:02.017 に答える