2009-08-03 17 views
8

これは一般に、経験を清潔に保ちながら漸進的なエンハンスメントを管理する方法ですが、どれだけ安全ですか?競合状態の可能性はありますか?これは機能しませんか?準備完了状態の前にdomを操作しても問題ありませんか?

これは私がやってしまいますどのような一般的である..あなたは、あなたがJavaScriptのサポートを持っている場合は、異なる何かを表示したい、シンプルな抽象的なシナリオを想像:

<div id="test">original</div> 
<script type="text/javascript"> 
    var t = document.getElementById('test'); 
    t.innerHTML = 'changed'; 
</script> 

多くは、あなたがフレームワークを使用する必要があると主張し、待つことdomreadyイベントのために、そしてそこに変更を行います。しかし、 'test'要素がドキュメントの終わりの前にすでにレンダリングされていて、CSSが準備できてdomreadyがトリガしているので、顕著なちらつき「オリジナル」の

このコードは競合状態の障害が発生する可能性がありますか?スクリプトの前に要素が存在していれば、その要素が検出可能で変更可能であることがわかりますか?

ありがとうございます。

答えて

5

問題はありますが、それには問題があります。

最初に、IEで閉じられていないノード(JSの下にある閉じるタグの前にBODYなど)を操作しようとすると、IEの「操作違反」エラーが発生し、空白ページ。ノードの操作には、ノードの追加、ノードの移動などが含まれます。

他のブラウザでは、動作は未定義ですが、通常は予期したとおりに動作します。主な問題は、ページが進化するにつれて、ページの読み込み/解析/実行が異なることです。これにより、ブラウザーが参照された要素を実際に作成してDOM操作に利用できるようにする前に、一部のスクリプトが実行される可能性があります。

あなたのユーザーの知覚されるパフォーマンス(つまり、スナッピング性)を向上させようとしている場合。私はあなたがこの道を避け、あなたのページを明るくすることを強く勧めます。 YahooのYSlow/GoogleのPage Performance Firebugを使用して、始めるのを手助けすることができます。

Google's Page Speed

Yahoo's YSlow

+0

Raegxさん、こんにちは、私は完全に理解できますが、操作が中断されました。オープニングのbodyタグの下にある可能性があります。そして、私のページの明るさにかかわらず、domreadyが発生する前にレンダリングされます。私はちょっとした経験を避けようとしていますそれは常にdomreadyでこのようなことを経験しています。 – meandmycode

+0

暗闇の中に戻って、私たちはonDomReadyを起動するクロスブラウザの方法を持っていなかったときに、すべてのimages/css/etcが読み込まれてレンダリングされた後にonLoadを使用していました。これで、DOMが解析されて表現された後に起動されますが、潜在的に画像/ etcの前に発生するonDomReadyがあります。これは比較的新しい進歩です。 OnDomReadyを待っているのは、私たちが今の時点で持っていることと、頑強さのための最良のソリューションです。 あなたがonDomReadyの前の操作が価値があると思われ、閉じられていないノードにノードを追加/作成/移動していないと思われる場合は、おそらく問題ありません。 –

+0

私が聞いているところではうまくいくはずですが、うまくいくはずですが、正式には要素が終了ノードの後に​​準備されるべきであるということは何も述べていません。 – meandmycode

3

DOMは完全に読み込まれる前に操作できますが、危険です。明らかに、操作しようとしているDOMのビットが実際に存在することを保証できないため、コードが断続的に失敗する可能性があります。

+0

おかげでrikh、あなたが保証をtheresの何を意味していますIE 5およびNavigatorで例外をスローします(ff、ie、operaなど)。私は、パーサーが線形に動作し、要素を追加すると思います。これは仕様ではないかもしれませんが、私はこれが賢明な振る舞いだと思うでしょう、そして、これが正当な答えを見つけるためにもっと探していました。 – meandmycode

+1

正直言って、私は知らないが、それは私が依存したいと思うものではない。誤った情報が表示されることが本当に心配な場合は、最初は何も表示せずに、docの準備をしておくか、システムから問題を設計してください。 –

+0

残念ながらそれはできません。最後の例は、ページ番号をハイパーリンクとしてレンダリングし、javascriptが実行され、これらを変更して 'Page x of y'を表示し、アクティブなページのハイパーリンクを強調表示できますアンカー)..これは、javascriptなしで動作するものをレンダリングし、次にjavascriptを使用してjavascriptを使用してそれを変更して変更する典型的なプログレッシブ・エンハンスメント・シナリオです.JavaScriptを使用して操作することができます。 。 – meandmycode

1

限り、あなただけ(すなわち、ノードの終了タグは、スクリプトの開始タグをpreceeds)スクリプトブロックをpreceedノードを変更するよう、あなたは何の問題が発生することはありません。

操作が成功したことを確認したい場合は、try...catchブロックにコードをラップし、エラーが発生した場合はsetTimeout()経由で再度呼び出します。

+0

ありがとうChristoph、私は失敗したときに何も戻ったり、例外を取ったり、再試行することができると考えていました。私はそのような再試行のロジックが気に入らなくても、実行がページの読み込み性能を妨げるかもしれないと心配しています。非常に拘束された帯域幅をシミュレートしようと試みることによっていくつかのテストを実行できるかどうかを見て、存在するすべてのウィンドウを見つけることができるかどうかを調べるために低い処理能力さえあります。ページの読み込み100バイト秒(それはしばらく時間がかかります..)と領域が既にロードされている時間が... – meandmycode

+0

..スクリプトを完璧に細かく実行..私は処理時間を制約する可能性が非常に高いと思いますパーサを壊して、仮定が間違っている窓を照らす。 – meandmycode

0

Viajeros.comでは、私は8-9ヶ月間働いているローディングインジケータを持っており、これまでのところ問題はありません。それは次のようになります。

DOMへのアクセス
<body> 

<script type="text/javascript"> 
    try { 
     document.write('<div id="cargando"><p>Cargando...<\/p><\/div>'); 
     document.getElementById("cargando").style.display = "block"; 
    } catch(E) {}; 
</script> 
+2

これはすべてのコードではないかもしれませんが、 'getElementById'は完全に不要であることを理解していますか? 'style =" display:block "をHTMLに追加することができます。 – DisgruntledGoat

-1

は時期尚早仕様によって、あるいは、今日存在する製品の実際の現実で、4

関連する問題