Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IE compatibility #16

Closed
cthedot opened this issue Jan 12, 2012 · 21 comments
Closed

IE compatibility #16

cthedot opened this issue Jan 12, 2012 · 21 comments

Comments

@cthedot
Copy link

cthedot commented Jan 12, 2012

hi,
first thanks for this great plugin.

It seems to work in IE sometimes, but not always (esp in IE8 but also 9). Seems IE gets tripped by the set to blank "hack" (it is a hack for webkit AFAIU, is it not?). I added an IE check (I know not good practice but the hack seems for webkit and maybe should stay for webkit only) and only if not do the "this.src = blank;" thing. Firefox does not seem to bother either way by the way...

I had the IE problem specifically with http://tympanus.net/codrops/2011/09/05/slicebox-3d-image-slider/ which includes the imagesloaded plugin but even after update to newest was most of the times failing (the demo seems to work but on a busier page it mostly did not).

If you want I can add the complete code.

Have you run into such an issue somewhere? I tested under Windows 7 64bit IE9 and 7/8 compat mode settings.

Thanks!

@darsain
Copy link
Collaborator

darsain commented Jan 17, 2012

I don't get it. What is happening in IE? What does it mean that "IE gets tripped"?

You should elaborate, or even better, reproduce the issue in http://jsfiddle.net/ if possible.

@cthedot
Copy link
Author

cthedot commented Jan 17, 2012

tripped meaning IE stops loading completely or/and does not trigger complete. I'll try to add an example though.

@grmlin
Copy link

grmlin commented Feb 2, 2012

Hi,
I have the same problem sometimes, but it's hard to reproduce. For some images the load handler didn't fire now and than.

I fixed it (I hope ;)) using new Image objects for the load handler.

$images.each( function() {
    // find out if this image has been already checked for status
    var cachedEvent = $.data( this, 'imagesLoaded' );
    // if it was, trigger the corresponding event and finish
    if ( cachedEvent ) {
        $(this).triggerHandler( cachedEvent );
        return;
    }
    var img = new Image();
    $(img).bind( 'load.imagesLoaded error.imagesLoaded', imgLoaded );
    // cached images don't fire load sometimes, so we reset src.
    var src = this.src;
    // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
    // data uri bypasses webkit log warning (thx doug jones)
    img.src = blank;
    img.src = src;
});

@cthedot
Copy link
Author

cthedot commented Feb 2, 2012

reproducing was actually a real problem. Fix for me was
...
if ($.browser.msie) {
this.src = '';
} else {
this.src = blank;
}
this.src = src;
...

so to not use the webkit specific hack which seemed to have caused wrong load things in IE IMHO.

@darsain
Copy link
Collaborator

darsain commented Feb 3, 2012

@grmlin your solution destroys the functionality of proper/broken images differentiation, as the events are triggered on a new Image() instead of image element in DOM that we are interested in, thus disabling us to track and provide objects of proper/broken images as callback arguments. Also, I don't see how this could fix anything, but IE behavior tends to go against reason pretty frequently... (btw, you don't have to img.src = blank if you already have a blank new Image())

@cthedot even if this would work (which seems unlikely, but as I've mentioned, IE has been always weird...) we can't use that as jQuery.browser might be removed in future versions of jQuery. Also, it is a bad practice :)

Nevertheless, I wanted to see what are you guys talking about, so I've had to create a more extensive testing examples. It even made me do the loremImages plugin :)

So here are the pages I came up with: Dynamically inserted images test & Static images test

Dynamic test is loading 100 random 300-400x400 pixels big images with 2% chance for loading broken ones, while static test is just set of 100 random images already included in HTML (just to be sure that dynamic insertion is not fixing the problem from whatever reason).

When the pages were done, I've fired up some podcast so I'd have something to listen to while I was spending an hour refreshing page in IE7, IE8, and IE9. Aaaaaaaaand there was not one time the plugin would misbehave, or callback would not fire. Not once ....

It is also good to note that I'm testing IE7 & IE8 in IETester (which is not 100% reliable, but it is as close as it gets without running virtual machines), but IE9 is native, and it still had no problem executing all callbacks.

So what now?

Sometimes it takes a long time for a browser to decide whether an image is broken or not (even ~10 seconds). Could it be that you were impatient and decided that it didn't fire while one of the images was still in loading state? Or are you using deferred.done() callback while one of your images decided not to load? Because .done() method will not fire in case there is at least one broken image.

@grmlin
Copy link

grmlin commented Feb 4, 2012

@darsain You're right of course, I forgot broken images as I don't have to deal with them in the project using you code.
For the new Image(): I tend to try things randomly for IE without too much thinking ;) This worked for me in the past in a custom image loader. I remembered, tried, and my page loaded fine.
I'll remove the img.src = blank, of course.

I'll look into your great test with an IE after the weekend.
The site having problems in IE here is static, has no broken images and fails without the new image workaround. IE9 is fine, only IE7 and IE8 are problematic. A last idea would be to use a real IE7 for testing, not the IE9 in IE7-mode. The IE7-mode did strange things in the past already, so maybe this is a problem.

@cthedot
Copy link
Author

cthedot commented Feb 4, 2012

@darsain A more general comment (and BTW, thanks for your work, still great!): I know browser sniffing including jquery.browser is "bad" practice but IE is bad practice too ;)
And at least in my pityful (and sadly not recreatable experience) the webkit "fix" broke IE. IMHO hacks are hacks and if they include browser sniffing that is ok as it they are hacks anyway... IMHO maybe the webkit only workaround "hack"/fix should have checked for webkit too? That would have been more safe meaning less chance for interference with other browsers, would it not?

On a somehow unrelated but OTOH strangely related incident I run into a jquery plugin (any some of my own code) using Modernizr to "feature" check for css3 3d transforms. Firefox 10 which does support these now but still failed on both the jquery plugin and my own code as Firefox works slightly differently (e.g. perspective(100px) instead of webkits perspective(100)). Guess what I am trying to say is that even feature detection does go wrong sometimes. Guess this is not the place to discuss this issue here though ;)

@cthedot
Copy link
Author

cthedot commented Feb 4, 2012

@darsain I tried the testpage in IE8 and 9 with a lot of pressing F5 for reloads in between loads or just hitting RETURN when on the URL bar or reloading by pasting the URL over and hit RETURN. Seems it does work, had 1 or 2 hickups though when apparently the browser seemed to have finished loading but the callback was not triggered.

My specific problem was with a lot less images (4-5) which were much bigger though (~80-120kb each) in which the problem was much more frequenst. I guess this would be a major hassle but of course it would be nice to have a static testpage with only a few but larger images on. Also this would be easier to test with lots of reloads in between loading.
Guess most users would try to reload a page if it takes more than 10seconds to load...

Anyway, thanks for your work!

@darsain
Copy link
Collaborator

darsain commented Feb 4, 2012

Ok, I've added two more tests: Big images dynamic & Big images static

Plus, all test pages now load experimental version of imagesLoaded plugin. The change is basically this:

var BLANK = window.console ? 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==' : window.location.href+'#';

Reasoning:

We are using data uri so the console would not be polluted with reports about missing/broken resources. If there is no console (IE6, IE7, and IE8 before you fire dev tools), use window.location.href suffixed with empty hash as a blank src (to not cause more HTTP requests, but also to have a way to check if an event was triggered on a blank image).

This should stop forcing IE7 & IE8 to render bunch of data-string images, which seems to be freezing, or doing something to your IE's.

The problem with this is, that IE8 registers window.console when you open IE8 developer tools, or are reloading page with dev tools already open. This almost never happens in "real world", but it is not a bulletproof method, so I'm not too happy with it.

Anyway, try to test it (in IE8 without dev tools open), but I think I'm done here until there will be more information about what exactly is happening to you :)

@cthedot
Copy link
Author

cthedot commented Feb 4, 2012

@darsain I admire your patience :) (really!)

Just to understand the test now: The "big static" should load all pictures and do the callback (Deferred is resolved) each time, there should not be broken images when using the default page? Right?

If so:

  • IE8 seems very fine now. I still need to port this over to the actual page I had the problem on (where other stuff is going on) to confirm but looks good
  • IE9 does - very seldomly though, maybe 1/10 reloads via F5 - show 1-2 broken images and a red "Deferred is rejected". If I understand the static test right this should not happen? Seems IE sometimes gets images from cache and this does not work properly?

If I did not understand the test right I am sorry and please correct me. I check the latest code on the original page at work at the beginning of the week anyway again...

Anyway, thanks a lot already!

@darsain
Copy link
Collaborator

darsain commented Feb 4, 2012

If the progress bar loads to the end, and ANY information about loaded/proper/broken images or deferred state is displayed, it means the plugin works correctly. The purpose of imagesLoaded is no longer only a callback after images had finished loading, but also providing the data about broken & properly loaded images, as well as images loading progress. That's what the dynamic testing pages are trying to do - display the whole functionality of this plugin. They are randomly loading broken images (with 2% chance in original test with 100 images, and 10% chance in 10 big images test, as it is written in the footer of each testing page), and reporting their state after they've finished with loading. Static pages are already pre-populated with constant set of images (97 proper/3 broken in 100 images test & 10 proper / 0 broken in 10 big images test), and their purpose is just to verify that inserting images with jQuery and than calling imagesLoaded has no effect on a bug that you are reporting here.

So again, if the progress loads to the end, and information about image stack is displayed (Total/Proper/Broken count & Deferred state), than everything works fine.

@cthedot
Copy link
Author

cthedot commented Feb 5, 2012

in that case the testpages work for me, still need to try in realworld example but looks very good. Thanks a lot!

@cthedot
Copy link
Author

cthedot commented Feb 6, 2012

@darsain
I put the code you provided on the example page on my real world page and again it failed in IE8 :(

After changing it to the following it does work though:

var BLANK = (!$.browser.msie) ?
'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==' : '';

  1. what is the reason to set BLANK = window.location.href+'#' for IE? Setting it to the empty string '' seems to do the trick (actually the only real change, the other change is for easier development only, see following)
  2. I normally develop for all IEs (8 and 9 for most of our client projects only luckily ;) in IE9 with IE8 mode which for most stuff seems sufficient. I know there are differences to a native IE8 but for most development stuff like most CSS layout problem this way is the easiest, fastest, most convenient and I assume the most common setup.
    So I did change the test for IE back to the jquery browser setting as IE8 mode in IE9 (and I assume also IE10) does (sometimes) have a console so the test for it is not really practical. I understand your reason to not want to use $.browser. But the jQuery docs only say the it "may" be removed and not that it will be. And even if removed will probably be moved to an extension. So I still think it is quite safe to use. Guess the safest and most reasonable would be to check for support of data URIS (quick search for it provided e.g. http://weston.ruter.net/2009/05/07/detecting-support-for-data-uris/) but I am not sure how reliable this will be. I did not find any check for data-URI in Modernizr which seems strange. I somehow assume if there is no test there there is no really reliable test but this might be wishful thinking ;)
    Guess my point is testing window.console as a test for an older IE is not really practical.
  3. Again I am sorry I cannot really provide a testpage. The page I work on is on a page for a client of ours which has a bit of other stuff on it. Also it is in a Typo3 (CMS) page which may influence stuff further (HTTP headers and such). But I tested it this morning with the code you provided which failed in IE8 (not 9!) and the 1 line change which did works everywhere.

I try to install XP Mode with a "proper" IE8 but still have no high hopes for being able to provide better testpages.

What do you think?

@darsain
Copy link
Collaborator

darsain commented Feb 7, 2012

Setting BLANK to empty string breaks the plugin. If it seems OK to you, than it is just a coincidence :) If you set img.src to blank, it falls back to the current window.location.href, and plugin is than unable to check if the event was fired on an image with BLANK src, or a normal image. That's why window.location.href+'#'.

If you are testing it in IE9 with Document mode: IE8, than window.console is obviously registered and my fix won't have any effect. Nevertheless, testing JavaScript related stuff in IE9 & Document mode is kinda pointless, as Document mode changes only the rendering engine (HTML+CSS, and even that is not really reliable according to a lot of people), but JS engine stays almost the same. The most reliable way is to install Windows VPC images, or at least the IETester, which is still not 100% accurate, but definitely more than IE9's Document modes.

Modernizr check for data-uri is here. I haven't used it as IE8 does support data-uris, so it was pointless. That's why window.console seemed more practical, as there is virtually nobody using native IE8 and browsing with opened Dev tools. But as I've already mentioned, even with the small chance of IE8 having registered console on load, it is not 100% reliable, I'm not happy with it, but thus far I haven't had a better idea.

If $.browser gets dropped, it would mean that everyone using imagesLoaded would have to install another plugin as a dependency, which is unacceptable. It is one thing to drop support for old things, and completely another to introduce future headaches for everyone using your stuff. Imagine a guy with 20 bundled plugins updates jQuery to a new version, and suddenly his page doesn't work because one of the plugins was deliberately using deprecated jQuery APIs... personally, that would piss me off :)

Yes, we could test for a browser inside the plugin, but I'm really struggling with doing such a bad practice to fix a bug that I've yet to consider as confirmed. I mean, seriously guys... none of you provided any examples, or described the problem. I had to spent few days creating testing pages and deducing myself what could be the issue from your reports, and now it seems that you are not even testing in a proper IE environments.

Right now - for me - it seems the problem is in IE8, and that it "freezes" or does "something" to the imagesLoaded execution when it has to render bunch of data-uri images that will get immediately replaced by normal urls. But I don't know if that is even semi-accurate anymore... I wish I could install VPC images myself and test it, but that won't be possible for some time.

I'll try to figure something out.

@darsain
Copy link
Collaborator

darsain commented Feb 7, 2012

OK, I've changed imagesLoaded version in test pages to the current one where BLANK is always data-uri and asked a friend with WinXP + IE8 to test all 4 versions of the page. He refreshed each one around 20 times and not one of the tests ever failed to him. Callback was always fired.

So... I'm not gonna include any changes related to this issue into the imagesLoaded, but I'll leave this issue open. Even when I do not consider this bug to be confirmed, one friend is still not enough for me to dismiss it either :)

@cthedot
Copy link
Author

cthedot commented Feb 7, 2012

@darsain

First, thanks very much for your patience, considered effort, patience and informative answers!

Today I installed XP Mode with (really) native IE8 on my work PC and tested the whole stuff again and from the begining. I have to admit and need to confirm that the plugin does work now. I might stand as a complete idiot and if you are majorly pissed off I'd understand that and am sorry for all the hassle.
For my own sake I hope for you having the complete testpages might be worth at least something and also confirmation IE8 does work... IE7 mode (tested in IE8) does work too, but might have the same pitfalls as the IE8 Mode in IE9.

At least to me the "testing JS for IE8 in IE9 is unusable" was news even as I see myself as a somewhat experienced webdev... (And for proper development for IE8 almost a complete desaster esp when IE10 comes out. I guess hardly any developer will install XP Mode or any VM just to test for this stuff. Also if you still need to dev for IE7 or even 6 this is almost impossible to do. And it seems there are hardly any Windows webdevs out there any more anyway - another topic alltogether.)

Anyway, thanks for the plugin and at least I have learned something (again). Sorry again but also much thanks!

@zhiwan
Copy link

zhiwan commented Feb 8, 2012

Hello.

I believe I am having a similar problem, but it seems for only IE 9. My site uses your plugin here: http://216.224.183.126/category/work/

As far as I can tell, I cannot find one consistent pattern to when IE9 decides to allow imageLoad to work or not. I have been trying to debug it for the past few days as sometimes there will be a long string of successful loads, and then it will switch. Have tried it on different computers at work.

It works on Firefox, Chrome, Safari, and IE8.

@darsain
Copy link
Collaborator

darsain commented Feb 8, 2012

@zhiwan duuude, that's one hell of a mess in code you got there! :) So lets fix you up.

First of all, the problem is not in imagesLoaded. The plugin works (at least the current version). And despite the mess I see in your scripts - it is quite surprising - but the problem is not really even in your code :)

The problem is in isotope plugin, which has the old version of imagesLoaded bundled in. That on itself is not a bad thing, but isotope is not checking whether the imagesLoaded is already present or not, it just overwrites it! ... and it is overwriting it with the old buggy version. I've fixed your site simply by CTRL+F for "fn.imagesLoaded", found the place where the isotope is overwriting it, renamed isotope version of fn.imagesLoaded to fn.getOutOfHere, and your IE problems disappeared.

Quick fix for you? Place/Load imagesLoaded plugin AFTER isotope.

@zhiwan
Copy link

zhiwan commented Feb 9, 2012

Hoooollyyyy Mooollyy. How did you go through my mess so quickly? Yah...this is my first foray into writing lots of jquery code and with an extremely finicky client under a short time constraint. I hope next time it will be cleaner.

I tried placing the imagesLoaded plugin after isotope but that didn't seem to solve it. But replacing fn.imagesLoaded with fn.blah worked.

Man...thanks so much!

@darsain darsain closed this as completed Feb 26, 2012
@deepfriedmind
Copy link

I don't mean to dig up a corpse thread but I was having problems with images not loading in IE7 (native version in VM). It would only happen randomly upon refresh and IE8/9 work fine. I was curious to try out the test pages that were posted but they're down. However, I just want to confirm that Darsain's suggestion works, i.e:

var BLANK = window.console ? 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==' : window.location.href+'#';

Shouldn't this be included in the plugin? I know using the presence of a console object as basis isn't optimal, but isn't it better than to have it randomly break in IE7?

@desandro
Copy link
Owner

@deepfriedmind I appreciate you chiming in. But we have to be realistic with the hours spent on maintaining this resource, IE7 is way old and we're no longer officially supporting it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants