Closed yaoazhen closed 11 years ago
Thanks @yaoazhen! We've been meaning to start using the load event now that more browsers support it. :) -- J
Is this issue specific to v0.6.x or pre-existing?
@asilvas I haven't seen the issue. The css! plugin code has not changed since 0.4.x and was tested on IE9. Not sure what's going on yet.
I'm not seeing a problem in Opera 11.62. I will check IE9 later.
Thank @unscriptable , In Opera 11.61 on win7, I also see this issue, The js callback will before the css loaded when you visit http://jsfiddle.net/6BeDS/2/ at first time, second time it will using cache, It's same with IE9.
So in this sample, it will log the rgb(0, 0, 0) at first time, and log rgb(255, 0, 0) after.
I've been able to reproduce this issue in IE6-9 and Opera 11.61 (but not 11.62). Just to clarify: cross-domain css files are loaded correctly, but the loader does not always wait for the style sheet to finish loading before proceeding.
@yaoazhen Just FYI: If your app does not need to wait for the css file to finish loading, you could use the link! plugin instead.
-- John
Correctly, the loader does not always wait for the style sheet to finish loading before proceeding.
Sadly~ I have to load css file asynchronous, and wait them complete in my strange app.
Julian Aubourg has a css $.ajaxTransport that loads and waits for CSS. I do not know if it's been tested against this particular scenario but it might be worthwhile to investigate the technique he's using.
https://github.com/jaubourg/ajaxHooks/blob/master/src/ajax/css.js
I did some serious experimentation/research over the weekend and prototyped an entirely new solution. It's almost working everywhere (tested IE6+, FF3.6+, Chrome 19, Safari 5.2, Opera 11.62).
Any word on the progress of this issue?
Hey @jeffrose, @asilvas, and @yaoazhen!
I've hit a wall. It seems there's no way to do the following two things at the same time in IE, Opera, Safari, and old Firefox:
Safari and FF3.6-9 have no known way to detect 404s using <link>
elements (they don't even support onload!). IE 6-9 and Opera fire onload instead of onerror when a link url is invalid. The only way I've found to get around this is to use a different element (<object>
or <img>
) to detect 404s. This means there are two requests for the stylesheet url, one from the <link>
and one from the <object>
or <img>
. Browsers could potentially send two HTTP requests under this situation, although I've found in practice that it doesn't happen often. (Sorry, I don't have more exact information about which browsers send two HTTP requests and under what conditions.)
Any feedback on what the best approach might be here?
Is it important to detect 404s?
Should we timeout (wait 1 sec, for instance) before trying to detect a 404 with an <object>
or <img>
?
Thanks!
Just FYI: I've got a fairly solid algorithm to detect when a browser supports onload and onerror. Therefore, as browsers start to support these events, whatever hacks we have in place will slowly become obsolete.
-- John
What I'm think about is shall we load all css with text, and then take the text into a style tag,and I'm force on this way now
@yaoazhen Loading as text would not be permitted across domain boundaries.
It's an unfortunate limitation, but using a long-running timeout (~5secs) for unsupported browsers seems more reasonable than losing the feature, so long as it does not add a lot of bloat, and is reliable.
I was hoping looking at @jaubourg CSS ajax transport would help with a solution but I guess it's simply a difficult problem to thoroughly solve cross-browser.
I do not believe it's important to detect 404s. It seems like a problem that would require developer intervention to resolve and there are other tools that give you the means to detect it, e.g. the Network tab in the Firebug console.
Not loading duplicate stylesheets seems like a useful optimization but couldn't that be somewhat achieved at build time? For instance the RequireJS optimizer traces the code facilitates bundling the JS in a "smart" way. That's not to say you will never fetch duplicate code, but if you take the time to configure and tweak the build optimizer, it should be infrequent. The same result could be achieved with CSS.
In regards to timing out, I would say check the loader configuration and use whatever timeout value is available, e.g. waitSeconds in RequireJS, with the option of also setting a css-specific timeout in the configuration, e.g. cssWaitSeconds.
@unscriptable would love to see your approach, even if flawed, somewhere. Maybe we can devise a plan to mitigate the issues you have but that would require some code to look at.
I haven't tested the ajaxHooks css transport recently (not enough time these days) so it's very possible something is broken in recent versions of FF and Chrome. Curious about the way you detect onload support.
Oh and hi everybody :)
I pushed a fix for the css! plugin to the dev branch. Please test it in your projects when you get a chance.
Summary:
This version:
The following browsers have working onload and onerror event handlers for elements. The plugin detects this and uses them (yay for working browsers!):
Firefox 12+ Chrome 10+ (?) Safari 6+ (and iOS 6+)
The following browsers use a crazy work-around to capture onload and onerror events (which also works around 31-stylesheet limits):
IE 6 (does not fire onerror) IE 7-9 (yes, IE9 still has the 31-sheet limit, despite claims to the contrary)
The following browsers have working onload, but not onerror event handlers. These don't fail silently, however. They fire a false onload event instead of an onerror event:
IE 10 Opera (all versions. tested up to 12.01)
All other browsers (old FF, old Chrome, old Safari, old Safari Mobile) use the "universal work-around" that sniffs for stylesheet rules. These browsers fail silently if a stylesheet is missing, unfortunately. If this is unacceptable behavior, then we'll have to add a timeout feature of some sort. I'm hoping to avoid this since it's nearly impossible to set the timeout to something reasonable for all users.
Feedback welcome! Thanks guys!
Hey @jaubourg!
Take a peek at https://github.com/cujojs/curl/blob/dev/src/curl/plugin/css.js
Unfortunately, there's a lot of shiz in there to deal with older browsers and IE. Basic approach:
Regards,
-- John
Very nice, John. Thanks!
There were still some issues with the latest Opera and XD stylesheets. There's a fix in the dev branch.
see #134
In function isLinkReady, if we visit 'sheet.rules', it will throw a error -'Access is denied' in IE9. This will make isLinkReady return true, then it will break the loop of function ssWatcher below. Actually, link.readyState and onload is support in IE9, it could be complete the loading. And (sheet.cssRules || sheet.rules) would be true, not 'Access is denied' when readyState is 'complete'.
The sample example: http://jsfiddle.net/6BeDS/2/ (By the way IE9 can reproduce the issue only you clean the cache, because IE will using the cache css, even you using ctrl+F5 )