jQuery事件在CSS加载后触发?

26
我页面上有几个链接(在<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需要更长/更短的时间,那怎么办。

让我知道是否需要澄清任何事情,我可以提供更多代码。


阅读此链接:http://www.alistapart.com/articles/alternate/ - Pointy
有趣的,谢谢Pointy。我需要background-color属性来做一些JQuery魔法,重新加载我的图片,但是,是的,那是一个很好的使用cookie的实现。 - Dave
https://dev59.com/bHA75IYBdhLWcg3wDUgo - mplungjan
6个回答

20

你可以使用 AJAX 调用来获取样式表的内容,并将其插入到内联样式块中,而不是创建一个新的链接元素并将其附加到 head 中。这样,你就可以使用 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'));
  });
});

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


1
是的,你漏掉了几个括号,但它运作得很好。谢谢! - Dave
1
这可能会破坏你的相对路径。 - alex
这是一个非常好的观点。如果你在CSS中使用根相对路径或绝对路径,就可以避免这个问题。 - Ben Hull

13

当加载CSS样式表时,可以监听与URL相关的任何元素的负载事件,这对您不起作用吗?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,谁会想到呢?


2
谢谢,我稍微修改了一下就让它工作了... $('head').append('<link id="ss1" type="text/css" href="'+path+'" rel="stylesheet" />'); $('#ss1').load(function(){alert("Loaded");});唯一的问题是,这似乎只在IE上有效。请参见http://www.daniweb.com/forums/thread257850.html。我也无法在Firefox等浏览器中使其工作。 - Dave

0
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
你可以使用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

如果你正在寻找一种方法,在确保外部样式表已经懒加载和渲染后,删除关键CSS(元素),那么你来对地方了。这将使我能够在多个项目中全局使用通用但视觉上令人愉悦的关键内部CSS。 由于一些关键样式在视觉上与懒加载的样式相冲突,因此它们需要被覆盖(工作量太大)或删除。简而言之,这就是我想要的:

  1. 使用关键内部CSS加载文档
  2. 在文档呈现和交互后懒加载其他CSS(有利于SEO和UX)
  3. 在花哨的附加样式表已经被加载并真正渲染后,从HTML中删除关键CSS,以防止所有其他解决方案中出现的闪烁问题(我已经进行了很多测试)。

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

-2

您可以简单地持续检查背景颜色是否仍然相同,如果发生变化,则执行您的操作。

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

1
如果有其他选项,像这样进行轮询通常不是一个好主意。 - Kasper Peeters
@Kasper Peeters,你在一篇帖子发布1年半后才投下反对票,这似乎有点奇怪。此外,你的投票理由最多只能算是含糊其辞。在加载事件上开火确实更优雅,但从其他答案来看,跨浏览器兼容性并不容易实现。我不会说我的解决方案一定更好,但它完全可以胜任工作,那么问题出在哪里呢? - aaaaaaaaaaaa
1
我认为这个解决方案的真正问题在于你无法确定颜色(或其他任何东西)是否会改变。可能只是由于任何一个被监视的样式从一个样式表到另一个样式表都没有改变,从而导致无限循环。 - Oliver
@Oliver 取决于你需要它做什么,我只能想到一个合理的用例,将与背景颜色无关的内容匹配到背景颜色上,对于这个目的,如果背景不改变,函数不触发也没关系。它旨在无限循环,但它不会阻塞并且占用CPU资源较少,所以这不是问题。 - aaaaaaaaaaaa
虽然这不是一个很好的解决方案,但它可以工作,所以如果没有其他办法,应该考虑使用它。 - Jared

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接