Javascript 加载 CSS 后触发的 jQuery 事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2571164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:57:28  来源:igfitidea点击:

jQuery event that triggers after CSS is loaded?

javascriptjquerycsseventsjavascript-events

提问by Dave

I have a couple of links on my page (inside a <div id="theme-selector">) which allow you to change the CSS stylesheets:

我的页面上有几个链接(在 a 中<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;
});

Now, after I've changed the style on the page, I want to get the new background color, using the following code (which I put after the $('head').appendcall):

现在,在更改页面上的样式后,我想使用以下代码(我在$('head').append调用后放置)获取新的背景颜色:

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

The problem is, I think, that it takes some time for the browser to download the new stylesheet and I sometimes get the old background color in my alert message. Is there some event I can bind that will only alert me after all the stylesheets are loaded on the page?

我认为问题是浏览器下载新样式表需要一些时间,有时我的警报消息中会出现旧的背景颜色。是否有一些我可以绑定的事件只会在页面上加载所有样式表后才提醒我?

At the moment, all I can think of is using a setTimeout(function(){}, 5000);which isn't great, because what if it takes longer/shorter to load all the CSS on the page.

目前,我能想到的只是使用一个setTimeout(function(){}, 5000);不太好的,因为如果加载页面上的所有 CSS 需要更长/更短的时间怎么办。

Let me know if I need to clarify anything and I can provide more code.

如果我需要澄清任何事情,请告诉我,我可以提供更多代码。

采纳答案by Ben Hull

Rather than creating a new link element and appending it to the head, you could retrieve the contents of the stylesheet with an AJAX call, and insert it into an inline style block. That way, you can use jQuery's 'complete' callback to fire off your check.

您可以使用 AJAX 调用检索样式表的内容,并将其插入到内联样式块中,而不是创建一个新的链接元素并将其附加到头部。这样,您就可以使用 jQuery 的“完成”回调来触发您的支票。

$('#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'));
  });
});

I haven't actually tested this code, so there may be some syntax-y errors, but the logic should be sound enough.

我还没有真正测试过这段代码,所以可能会有一些语法错误,但逻辑应该足够合理。

回答by Michael

The load event can be watched for any element associated with a url, does this not work for you when loading the css stylesheet? http://api.jquery.com/load-event/

可以监视与 url 关联的任何元素的 load 事件,这在加载 css 样式表时对您不起作用吗?http://api.jquery.com/load-event/

Try something like this:

尝试这样的事情:

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);

Edit:As pointed out below this only works in IE, who would have thought?

编辑:正如下面所指出的,这只适用于 IE,谁会想到?

回答by user1774979

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;
});

successfully tested in Chrome 28, IE 10, FF22

在 Chrome 28、IE 10、FF22 中成功测试

回答by R. Oosterholt

You could use lazyload(jQuery plugin) to load a css file. It has the ability to call a function when the file is included.

您可以使用lazyload(jQuery 插件)来加载 css 文件。它能够在包含文件时调用函数。

Example:

例子:

// Load a CSS file and pass an argument to the callback function.
LazyLoad.css('foo.css', function (arg) {
  // put your code here
});

回答by marko-36

Got here looking for a way to remove critical CSS ( element) after being 100% sure, that external sheets have lazyloaded and rendered. This would allow me to use universal, yet visually pleasing critical internal CSS globally over several projects. Since some of the critical styles go visually against the lazyloaded ones, so they need to be overridden (too much work), or removed. This is what I want, in short:

100% 确定外部工作表已延迟加载和渲染后,来到这里寻找一种删除关键 CSS(元素)的方法。这将允许我在多个项目中全局使用通用但视觉上令人愉悦的关键内部 CSS。由于某些关键样式在视觉上与延迟加载的样式相反,因此需要覆盖(太多工作)或删除它们。这就是我想要的,简而言之:

  1. Load the document with critical internal CSS
  2. Lazyload the additional CSS after the document is rendered and interactive (good for SEO and UX)
  3. Remove critical CSS from HTML after the fancy additional stylesheets have been loaded and truly rendered, to prevent flickering which occured with all other solutions(I have tested this a lot).
  1. 使用关键的内部 CSS 加载文档
  2. 在文档呈现和交互后延迟加载额外的 CSS(有利于 SEO 和 UX)
  3. 在加载并真正呈现花哨的附加样式表后,从 HTML 中删除关键 CSS ,以防止所有其他解决方案出现闪烁(我对此进行了大量测试)。

A 100% working solution (may it be unpopular) is to use setInterval();after having the secondary css lazyloaded, to periodically check, whether a style, unique to secondary CSS has truly been applied. Then I can have the critical CSS removed (or whatever I want to do..).

100% 有效的解决方案(可能不受欢迎)是使用setInterval(); 延迟加载二级CSS后,定期检查是否真正应用了二级CSS独有的样式。然后我可以删除关键的 CSS(或者我想做的任何事情......)。

I have created a live demo with comments on Codepen: https://codepen.io/Marko36/pen/YjzQzdand some info in a blogpost: Triggering a Javascript/jQuery event after CSS has loaded.

我在 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);

回答by aaaaaaaaaaaa

You could simply keep on checking if the background colour is still the same, and then do your thing if ever it changes.

您可以简单地继续检查背景颜色是否仍然相同,然后在它发生变化时执行您的操作。

oldbackground=getbackground()
function checkbackground(){
    if(oldbackground!=getbackground()){
        oldbackground=getbackground()
        //Do your thing
    }
}
setInterval(checkbackground,100)