8

要素を作成してDOMに挿入し、すぐにdocument.styleSheetsコレクションで新しいスタイルシートを見つけようとするコード(実際には私のものではありませんが、SlickGridライブラリ)があります。<style>

WebKit では、これが失敗することがあります。実際にどのような状況なのかはわかりませんが、一貫して再現できるものではありません。load次のように、スタイル要素のイベントが発生するまで StyleSheet オブジェクトのチェックが行われないように、コードを変更することで回避できると考えました。

  $style = $("<style type='text/css' rel='stylesheet' />").appendTo($("head"));
  var rules = ...;// code to create the text of the rules here
  if ($style[0].styleSheet) { // IE
    $style[0].styleSheet.cssText = rules.join(" ");
  } else {
    $style[0].appendChild(document.createTextNode(rules.join(" ")));
  }
  $style.bind('load', function() {
          functionThatExpectsTheStylesheet();
  });

functionThatExpectsTheStylesheet は、次のように実際のスタイルシート オブジェクトを見つけようとします。

    var sheets = document.styleSheets;
    for (var i = 0; i < sheets.length; i++) {
      if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]) {
        stylesheet = sheets[i];
        break;
      }
    }

しかし、その時点でも、スタイルシート オブジェクトが見つからないことがあります。

だから、私の質問はこれです:

  1. 実際、このloadイベントは styleSheet オブジェクトが利用可能であることを保証していませんか? バグですか?
  2. そうでない場合、使用できる別の条件はありますか、それともタイムアウトを使用してこれを行う必要がありますか?
  3. または、load イベントをバインドする方法に問題があり、それが私の問題ですか?
4

4 に答える 4

0
  1. css スタイルシートよりも早く load イベントがトリガーされる可能性があると思います。この問題はおそらく10回に1回発生しますが、それでもベストプラクティスではなく、最もクリーンな方法です.

  2. setTimeout は、スクリプトが最初に css をロードすることを保証できるため、確かに良いアプローチです。ただし、スタイルシートのタグのみがリンクを作成することを意味するため、css を最初にダウンロードする必要があるため、これら 2 つのどのアプローチを使用しても、load イベントの前に css が読み込まれることが 100% 保証されることはありません。発火します。

すべてが正しい順序で実行されることを 100% 確実にするには、AJAX を介して同期ファイルを読み取るか、CSS の準備ができているかどうかを確認するヘルパー関数を使用して非同期 AJAX 呼び出しを行います (この方法では、ブラウザーをフリーズせずに機能を維持できます)。ファイルがロードされているかどうかを確認します)。もう 1 つの方法は、スタイルシート マニュアルをリンクすることです。最初にスタイルシートを設定してから、HTML ファイルのヘッダーにコードを挿入します。

読み込みイベントについては詳しく調べていませんが、DOMContentLoaded イベントは、CSS が読み込まれたときにのみ発生している可能性があります (これについてはよく調べていません)。

同様の質問については、ここを参照してください: CSS がロードされた後にトリガーされる jQuery イベント?

于 2013-07-19T13:54:17.300 に答える
0

スタイルのルールの検出を使用して、スタイルシートがロードされているかどうかを確認する必要がありました。

// Load CSS dynamically. There's no way to determine when stylesheet has been loaded
// so we usingn hack - define `#my-css-loaded {position: absolute;}` rule in stylesheet 
// and the `callback` will be called when it's loaded.
var loadCss = function(url, cssFileId, callback){
  // CSS in IE can be added only with `createStyleSheet`.
  if(document.createStyleSheet) document.createStyleSheet(url)
  else $('<link rel="stylesheet" type="text/css" href="' + url + '" />').appendTo('head')

  // There's no API to notify when styles will be loaded, using hack to 
  // determine if it's loaded or not.
  var $testEl = $('<div id="' + cssFileId + '" style="display: none;"></div>').appendTo('body')    
  var checkIfStyleHasBeenLoaded = function(){
    if($testEl.css('position') == 'absolute'){
      $testEl.remove()
      callback()
    }else setTimeout(checkIfStyleHasBeenLoaded, 10)
  }
  setTimeout(checkIfStyleHasBeenLoaded, 0)
}
于 2013-11-29T21:07:23.653 に答える