【问题标题】:jQuery event that triggers after CSS is loaded?加载CSS后触发的jQuery事件?
【发布时间】:2010-04-03 11:53:38
【问题描述】:

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

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

【问题讨论】:

标签: javascript jquery css events jquery-events


【解决方案1】:

您可以使用 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'));
  });
});

我还没有实际测试过这段代码,所以可能存在一些语法错误,但逻辑应该足够健全。

【讨论】:

  • 是的,你遗漏了几个括号,但它就像一个魅力。谢谢!
  • 不过,这会填满你的相对路径。
  • 这是一个很好的观点。如果您在 CSS 中使用相对根路径或绝对路径,您将避免该问题。
【解决方案2】:

可以观察与 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,谁能想到?

【讨论】:

  • 谢谢,我稍作修改就可以工作了... $('head').append(''); $('#ss1').load(function(){alert("Loaded");});唯一的问题是,这似乎只适用于 IE。见daniweb.com/forums/thread257850.html。我也无法让它在 Firefox 等中工作。
【解决方案3】:
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 中成功测试

【讨论】:

    【解决方案4】:

    您可以使用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
    });
    

    【讨论】:

      【解决方案5】:

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

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

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

      我在 Codepen 上使用 cmets 创建了一个现场演示:https://codepen.io/Marko36/pen/YjzQzd,并在博文中提供了一些信息:Triggering a Javascript/jQuery event after CSS has loaded

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

        • 如果有替代方案,这样的投票绝不是一个好主意。
        • @Kasper Peeters 在发帖 1.5 年后投下反对票似乎有点奇怪。除此之外,您投票的理由充其量也很模糊。在加载事件上触发肯定更优雅,但从其他答案来看,以跨浏览器兼容的方式不容易做到。我不会说我的解决方案一定更好,但它可以很好地完成工作,那么问题是什么?
        • 我认为这个解决方案的真正问题是你不能确定颜色(或任何东西,就此而言)会改变。可能只是监视的任何样式可能不会从一个样式表更改为下一个样式表,从而导致无限循环。
        • @Oliver 取决于您需要它的用途,我只能想出一个合理的用例,将非 CSS 的东西与背景颜色相匹配,为此,函数不重要并不重要如果背景没有改变,就不会开火。它意味着无限循环,但它不会阻塞和占用 CPU,所以这不是问题。
        • 虽然不是一个很好的解决方案,但它会起作用,所以如果没有其他方法应该考虑。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-02
        • 1970-01-01
        • 1970-01-01
        • 2018-08-04
        相关资源
        最近更新 更多