web-dev-qa-db-ja.com

CSSがロードされた後にトリガーされるjQueryイベント?

私のページ(_<div id="theme-selector">_内)にCSSスタイルシートを変更できるリンクがいくつかあります。

_$('#theme-selector a').click(function(){
  var path = $(this).attr('href');
  $('head link').remove();
  $('head').append('<link type="text/css" href="'+path+'" rel="stylesheet" />');
  return false;
});
_

ここで、ページのスタイルを変更した後、次のコード($('head').append呼び出しの後に配置)を使用して、新しい背景色を取得したいと思います。

_var bgcolor = $('body').css('background-color');
alert(bgcolor); 
_

問題は、ブラウザが新しいスタイルシートをダウンロードするのに時間がかかり、アラートメッセージに古い背景色が表示されることがあることだと思います。すべてのスタイルシートがページにロードされた後にのみ警告する、バインドできるイベントはありますか?

現時点では、setTimeout(function(){}, 5000);を使用することしか考えられません。これは、ページにすべてのCSSをロードするのに時間がかかる/短くなるとどうなるかという理由からです。

何かを明確にする必要があり、さらにコードを提供できるかどうかを教えてください。

24
Dave

新しいリンク要素を作成してヘッドに追加するのではなく、AJAX呼び出しでスタイルシートのコンテンツを取得し、インラインスタイルブロックに挿入することができます。こうすることで、 jQueryの「complete」コールバックを使用してチェックを開始します。

$('#theme-selector a').click(function(){
  var path = $(this).attr('href');
  $.get(path, function(response){
   //Check if the user theme element is in place - if not, create it.
   if (!$('#userTheme').length) $('head').append('<style id="userTheme"></style>');

   //populate the theme element with the new style (replace the old one if necessary)
   $('#userTheme').text(response);

  //Check whatever you want about the new style:
  alert($('body').css('background-color'));
  });
});

私は実際にこのコードをテストしていないので、構文上のエラーがあるかもしれませんが、ロジックは十分に健全であるはずです。

19
Ben Hull

ロードイベントは、URLに関連付けられている要素を監視できますが、cssスタイルシートをロードするときにこれは機能しませんか? http://api.jquery.com/load-event/

次のようなものを試してください。

var path = $(this).attr('href');
$('head link').remove();
var styleSheet = $('<link type="text/css" href="'+path+'" rel="stylesheet" />');
styleSheet.load(function(){alert("Loaded");});
$('head').append(styleSheet);

編集:以下で指摘するように、これはIEでのみ機能します。誰が考えたでしょうか。

12
Michael

lazyload (jQueryプラグイン)を使用してcssファイルをロードできます。ファイルが含まれているときに関数を呼び出す機能があります。

例:

// Load a CSS file and pass an argument to the callback function.
LazyLoad.css('foo.css', function (arg) {
  // put your code here
});
0
R. Oosterholt
var cssLoaded = function()
{
    alert($('body').css('background-color'));
};
$('#theme-selector a').click(function(){
   var path = $(this).attr('href');
   $('head link').remove();
   $('head').append('<link onload="cssLoaded();" type="text/css" href="'+path+'" rel="stylesheet" />');
   return false;
});

Chrome 28、IE 10、FF22で正常にテストされました

0
user1774979

外部シートがレイジーロードされてレンダリングされていることを100%確認した後、重要なCSS(要素)を削除する方法を探してここに行きました。これにより、ユニバーサルでありながら視覚的に心地よい重要な内部CSSを複数のプロジェクトでグローバルに使用できるようになります。重要なスタイルのいくつかは、レイジーロードされたスタイルに対して視覚的に影響するため、オーバーライドする(作業が多すぎる)か、削除する必要があります。要するに、これが私が欲しいものです:

  1. 重要な内部CSSを使用してドキュメントをロードします
  2. ドキュメントがレンダリングされてインタラクティブになった後、追加のCSSをレイジーロードします(SEOとUXに適しています)
  3. 派手な追加の後に重要なCSSをHTMLから削除します他のすべてのソリューションで発生したちらつきを防ぐために、スタイルシートがロードされて実際にレンダリングされました(私はこれをたくさんテストしました)。

100%機能する解決策(人気がない可能性があります)は、セカンダリcssをレイジーロードした後にsetInterval();を使用して、セカンダリCSSに固有のスタイルが本当に適用されました。次に、重要なCSS(またはやりたいことは何でも)を削除することができます。

Codepenに関するコメント付きのライブデモを作成しました: https://codepen.io/Marko36/pen/YjzQzd およびブログ投稿のいくつかの情報: CSS後にJavascript/jQueryイベントをトリガーしますロードされました

var CSSloadcheck = setInterval(function () {
    if ($('body').css('opacity') != 1) {
    //when opacity is set to 0.99 by external sheet
      $('style#critical').remove();
      clearInterval(CSSloadcheck);  
  }
}, 100);
0
Marko36