【问题标题】:Can a jQuery load event fire when adding a dynamic stylesheet in Firefox?在 Firefox 中添加动态样式表时会触发 jQuery 加载事件吗?
【发布时间】:2011-04-27 22:57:53
【问题描述】:

我在 jQuery 中运行以下代码来动态加载样式表。其目的是允许用户加载自定义样式表并更改 JavaScript 小部件的外观:

this.loadStyleSheet = function(url){
    $("<link rel='stylesheet' type='text/css' />").attr("href", url).appendTo("head");
}

屏幕瞬间出现跳动,因为只有在加载动态样式表后才会将正确的样式应用于小部件。为了解决这个问题,我需要知道动态样式表实际上是什么时候完成加载的。

虽然这个问题has been discussed before,但没有一个解决方案适用于我的情况:

  1. .load() 仅在 IE 中触发,而不在 Firefox 中触发。需要跨浏览器解决方案。顺便说一句,.ready() 在样式表完成加载之前触发。
  2. .get() 仅适用于同一域。在我的例子中,样式表可能来自任何给定的域。
  3. 无法通过 setTimeout 查询要更改的某些 CSS 属性。用户可能指向任何自定义样式表,但无法知道她的 CSS 文件将包含什么。
  4. 通过 setTimeout 加载样式表后等待一段时间显然是一个糟糕的解决方案。没有办法提前知道样式表需要多长时间才能加载,如果它会加载的话。

关于这个问题有什么新想法吗?非常感谢您的帮助。

【问题讨论】:

  • 现在我找到了一个有点脏的解决方案 - 将动态 CSS 负载移到 $(document).ready 之外,将其余代码留在 $(document).ready 中。因此,其余代码仅在加载动态 CSS 后执行。不过,我很想知道是否有其他解决方案。
  • 我并不是真的推荐这个,但如果你永远找不到答案.. 你仍然可以使用 .get() 方法。只需让它将样式表 URL 传递给您域上的 php 脚本,该脚本会获取 CSS 并返回它。

标签: javascript jquery css firefox javascript-events


【解决方案1】:

我最近遇到了同样的问题。我的解决方案是保持就绪事件并在 css 页面加载后释放它。我使用了$.holdReady jQuery 命令 document.ready 代码之外。那么,如何在 css 加载时触发事件?我在链接标签上使用了 onload 命令。代码:

$.holdReady(true);

$('head').append($('<link rel="stylesheet" type="text/css" 
    onload="$.holdReady(false)"/>').attr('href','myCSS.css'));


$(document).ready(function() {
    ...code here to execute after css loads
})

它适用于 FF 16。尚未检查不同版本或浏览器。另外,我认为链接标签上的 onload 事件纯粹是 HTML5。

【讨论】:

  • 这是一个巧妙的解决方案。我什至不知道holdReady。不幸的是,它在 Chrome 中不起作用。无论出于何种原因,在实际加载样式表之前解除保留。谢谢,尽管你为我指明了 holdReady 的方向。
【解决方案2】:

“.load() 仅在 IE 中触发,在 Firefox 中不触发。需要跨浏览器解决方案。顺便说一句,.ready() 在样式表完成加载之前触发。”

这很奇怪,.load() 在 Firefox 中对我有用。

“无法通过 setTimeout 查询要更改的某些 CSS 属性。用户可能指向任何自定义样式表,并且无法知道她的 CSS 文件将包含什么。”

虽然肯定不是一个理想的解决方案,但为什么不要求将某个字符串写入 css 文件的 cmets,然后您可以对其进行正则表达式?

其他想法: 您是否考虑过使用 propertychange 事件?

$(body).bind('propertychange', function(){ show_my_page_after_timeout(); });

这样您可以隐藏可能更改的页面元素,允许浏览器处理 css,然后在处理完成时显示这些元素(您甚至可以淡出和淡入)。如果在超时显示您的页面之前再次调用事件处理程序(例如 css 属性已更改),您可以通过设置一个短暂的超时来取消此操作。

【讨论】:

  • .load() 使用上面的代码在 Firefox 中为您工作吗?它通常可以工作,但是在将链接标签动态添加到标题时,它似乎崩溃了。
  • 是的......刚刚再次测试它。不过,一个大问题是它不能跨域工作,由于跨域限制(chrome 和 firefox)而不允许,所以这确实是一个非解决方案。我认为您必须坚持将 propertychange 事件处理程序绑定到任何适当的元素,并在应用更改期间隐藏内容。虽然很脏,但是要求本身很脏。人们应该从页面其余部分来自的域加载他们的样式表,你为什么要以其他方式?!
  • 好吧,正如我刚才提到的,我正在编写的大部分代码都是一个 JavaScript 小部件,用户可以将它嵌入到任何网站上。我的客户不想拥有自定义样式表上传服务,而是希望从任何给定位置获取自定义样式表。这有意义吗?
  • “用户可以嵌入到任何网站的 JavaScript 小部件。我的客户不想拥有自定义样式表上传服务”这确实有道理,但如果他们可以添加小部件那么肯定他们还可以添加自己的自定义 CSS 吗?例如,您可以加载 ./thewidget.css(带有更改路径的选项),然后用户可以将他们的自定义 css 放在他们想要的 webroot 中的任何位置。这不适用于哪些小部件使用/部署情况?小部件用户有多难?
  • 我很好奇,所以做了一些挖掘。你遇到过YQL吗? net.tutsplus.com/tutorials/javascript-ajax/… 我自己没用过,但如果您的客户坚持 css 必须可以从任何地方上传,它似乎可以解决您的问题。祝你好运! ;-)
【解决方案3】:

如果其他人需要对此的答案,请扩展我上面的评论:

您的 Javascript 将如下所示:

var style = $('<style type="text/css">');
$(document).append(style);
style.load('/fetchstyle.php', { url: "http://somesite.com/style.css" }, function() {
    // The styles are loaded
});

而 fetchstyle.php 脚本看起来像这样:

<?php
echo file_get_contents($_GET['url']);

未经测试,但这个概念应该可行。

【讨论】:

  • 它可能会工作,但我会更高兴与客户端唯一的解决方案。还是谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多