FireFox 3.5 Fetches Image Sprite Repetitively - how to prevent? - javascript

EDIT: Mozilla fixed the bug. This thread is dead.
EDIT: This is a Mozilla bug. See this thread: https://bugzilla.mozilla.org/show_bug.cgi?id=501853
I have a sprite I use for my images here: http://www.trailbehind.com/site_media/images/sprite.png
In FireFox 3.5, the sprite seems to get fetched every time I render an icon on my map, you can see the behavior in the Firebug Net Panel when you load this page and/or pan the map: http://www.trailbehind.com/node/1148091/
I had previously had similar problems to this in Internet Explorer, but I had eventually gotten this working in Safari 3/4, FF 2/3, and IE 6/7/8. Now, something is wrong in FF 3.5 :(
I tried to put this code in the of the document to prec-cache the image, but to no avail:
var pre = new Image();
pre.src = "/site_media/images/sprite.png";
Here's the code that later creates the map markers (and fetches the sprite image again). It might be GMaps related - it doesn't seem to fetch a sprite to draw each icon or otheer image on the left... just the map.
//returns an image-like GIcon based on a sprite
function getGIconSprite(attr) {
var myicon = new GIcon(G_DEFAULT_ICON);
myicon.sprite = {image:"/site_media/images/sprite.png", top:0};
myicon.iconSize = new GSize(16,16);
myicon.iconAnchor = new GPoint(8,8);
myicon.shadow = null;
myicon.sprite.left = attr.offset*16;
return myicon;
}

This is official FireFox 3.5 bug. Simple hack for it is to create two class for all snipped object: one common for all with background image, and the second one with background position.
That's all kids!)

There seems to be a problem with FireFox 3.5 loading images from the server and not using the cache properly. Google "firefox 3.5 not caching images" and you will notice a lot of people noticing this problem.

it is gmaps JS related. you should use a pointer (copy of variable) to the existing variable, such as:
defaulticon.sprite = {image:"/site_media/images/sprite.png", top:0};
myicon.sprite = defaulticon.sprite;
myicon2.sprite = defaulticon.sprite;
etc.

I see you use Lighttpd. You might want to use Module: mod_expire for your static files. Set them to expire after a month or even more. You can find more information about this on Yahoo.

Related

Javascript Preloading Images: Add to DOM, or not?

Is it necessary to add an <img> to the DOM in order to preload it?
$(function whenDOMIsHappy(){
var $img = $('<img />')
.load(loadHandler)
.error(errorHandler)
.attr({src:"squatchordle-squashgarden.jpg"});
$img.appendTo('body .preloads'); // is this at all necessary?
});
// assuming <div class="preloads" style="display:none;"></div> exists in <body>.
I've seen mixed messages about this technique. I'm using jQuery, but the question applies to vanilla-people too.
I am interested in keeping this working in all major browsers.
All browsers I've tested do load images even if they're not in the DOM. You can test this with https://jsfiddle.net/84tu2s9p/.
const img = new Image();
img.src = "https://picsum.photos/200/300";
img.onload = () => console.log("loaded");
img.onerror = err => console.error(err);
Safari 13, 11.1, 10.1
Edge 18
Firefox 72, 70, 62
Chrome 78, 71
Opera 64
IE11
(Not meant to be an exhaustive list. I just tried a variety of versions and browsers.)
There's also the new image.decode() API that is intended for this use case of preloading images and avoids potential dropped frames when actually decoding the image to render it. Edge doesn't support it yet (Chromium-based Edge will though).
Given that HTML Canvas can use images without them being in the DOM, I think they have to load images.
as opposed to creating and then appending elements to the dom, why not just initialize a new image in javascript, then set its source to your images URL. this method should load your image without actually applying it to an element or rendering it on the dom - YET... take a peek:
someImageArray[0] = new Image();
someImageArray[0].src = "http://placehold.it/700x200/";
from here you are free to do what you wish with that image using javascript - render it directly in canvas or create an element out of it. however you might not even have to do anything. say if its already being referenced in other ajax based content. provided the URL is identical, the browser should use the cached version to draw the dom.
hope this helps here is a reference to a decent article about pre-loading with a few more options...
There is no guarantee that Images will be preloaded if you don't add it to the DOM! If you don't add it, the JavaScript Compiler can aggressively garbage collect the Image before it tries to load, because the element is not used at all.
This currently happens in firefox! There your images will not be preloaded if you don't add them to the DOM! - So be on the safe side and add them.

View source not available in some browsers for dynamically created webpage

CONTEXT
I am creating an http://canvimation.github.com/ that uses javascript to create web pages dynamically.
The source code for my application is at https://github.com/canvimation/canvimation.github.com
The application uses Canvas to draw using vector objects the resulting drawing can then be exported as a web page. To create a web page click on the FILE icon and then 'Export Canvas to HTML'.
The exporting code opens a new window and uses document.writenl() to construct the code. The relevant function is shown at the end of the question.
All browsers I have tried produce the drawing correctly in the new window as a web page. In all browsers view source shows the expected code for the application web page.
In IE10 and Firefox it is possible to view the source of the exported code which can then be saved and the saved file used as a webpage.
For the exported web page: in Chrome 28 view source is greyed out and not available; in Safari 5 for Windows view source produces a blank window and in Opera 12 source does not do anything.
QUESTIONS
How is it possible to save or view the source of the exported webpage in Chrome, Safari and Opera?
Can anything be changed in my method to dynamically create a webpage that can have its source code viewed and saved?
RELEVANT CODE
function exportShapes()
{
var shapelist=[];
var nameZ=[];
for (var name in SHAPES)
{
nameZ=[];
nameZ.push(name);
nameZ.push(SHAPES[name].zIndex);
shapelist.push(nameZ);
}
shapelist.sort(compareZ);
newwindow=window.open('','export');
newwindow.document.writeln('<!DOCTYPE HTML>');
newwindow.document.writeln('<html>');
newwindow.document.writeln(SPACES.substr(0,3)+'<head>');
newwindow.document.writeln(SPACES.substr(0,6)+'<style>');
newwindow.document.writeln(SPACES.substr(0,9)+'#canvasarea');
newwindow.document.writeln(SPACES.substr(0,9)+'{');
newwindow.document.writeln(SPACES.substr(0,12)+'border:black 1px solid;');
newwindow.document.writeln (SPACES.substr(0,9)+'}');
newwindow.document.writeln(SPACES.substr(0,6)+'</style>');
newwindow.document.writeln(SPACES.substr(0,6)+'<!--[IF LT IE 9]><script type="text/javascript" src = "excanvas.js" ></script><![endif]-->');
newwindow.document.writeln(SPACES.substr(0,6)+'<script type="text/javascript">');
newwindow.document.writeln(SPACES.substr(0,9)+'function setcanvas()');
newwindow.document.writeln(SPACES.substr(0,9)+'{');
newwindow.document.writeln(SPACES.substr(0,12)+'var canvas = document.getElementById("canvasarea");');
newwindow.document.writeln(SPACES.substr(0,12)+'if (canvas.getContext)');
newwindow.document.writeln(SPACES.substr(0,12)+'{');
newwindow.document.writeln(SPACES.substr(0,15)+'var ctx = canvas.getContext("2d");');
newwindow.document.writeln(SPACES.substr(0,15)+'drawcanvas(ctx);');
newwindow.document.writeln (SPACES.substr(0,12)+'}');
newwindow.document.writeln(SPACES.substr(0,12)+'else');
newwindow.document.writeln(SPACES.substr(0,12)+'{');
newwindow.document.writeln(SPACES.substr(0,15)+'alert("Canvas NOT supported");');
newwindow.document.writeln (SPACES.substr(0,12)+'}');
newwindow.document.writeln (SPACES.substr(0,9)+'}');
newwindow.document.writeln (SPACES.substr(0,9));
newwindow.document.writeln (SPACES.substr(0,9)+'function drawcanvas(ctx)');
newwindow.document.writeln(SPACES.substr(0,9)+'{');
for(var i=0;i<shapelist.length;i++)
{
exportshape(shapelist[i][0]);
}
newwindow.document.writeln (SPACES.substr(0,9)+'}');
newwindow.document.writeln(SPACES.substr(0,6)+'</script>');
newwindow.document.writeln(SPACES.substr(0,3)+'</head>');
newwindow.document.writeln(SPACES.substr(0,3)+'<body onload="setcanvas()">');
newwindow.document.writeln(SPACES.substr(0,6)+'<canvas id="canvasarea" width="'+parseInt($("stagearea").style.width)+'" height="'+parseInt($("stagearea").style.height)+'"></canvas>');
newwindow.document.writeln(SPACES.substr(0,3)+'</body>');
newwindow.document.writeln('</html>');
newwindow.document.close();
}
If you are just trying to see the HTML after javascript rendering, then right-click > inspect element should let you see the code, at least in Chrome.
You should then be able to copy it manually - or do you need it to be done automatically?
I know in brython it's just in the variable doc.html, but that probably doesn't help you in javascript.
Similar Question
The problem is it's a blank page (about:blank), for which Chrome sees no reason to view the source code, because it should be empty. You may consider creating some sort of temp file and put all the canvas stuff into it.
Inspect Element option, suggested above, doesn't work in this case, it's not going beyond canvas tag. I suspect Chrome is rendering this as a picture, not as a vector graphics.

Setting an image source via Javascript unreliable in Internet Explorer

I am simply trying to change the SRC attribute of an image via javascript like so:
document.getElementById('fooImage').src = img;
Where img is a variable that has a link to the file.
In all other browsers (Chrome, Firefox, Safari) this works. In IE (7+) this also works too sometimes.
Using IE's built-in developer tools, I can see that the image's SRC tag is set. Is there something else in the locals window that could help me debug why the image doesn't actually show on screen?
I've also tried using jQuery to do this and same outcome:
$("#fooImage").attr("src", img);
An ideas?
In debugging this I would hard code it first...
document.getElementById('fooImage').src = "myimage.png";
I've used the following in my website and it works like this...
var imgCounter = document.getElementById('formtimer');
imgCounter.src = "graphics/odometers/1.png";
Some other things to check:
Make sure your ID= tag is not in the <DIV section but inside the <IMG section... for example <div class="style1"><img src="yourpicture" id="someid">. If `id='someid' is in the div tag then you can't change the picture / the picture won't show up.
are you using window.onload?, body onload? the proper way to use the first is..
window.onload = function () { YourFunctionHere(); };
Try a different test image. I had issues in the past with showing png's, I changed it to a gif or jpg and it worked. I don't understand how that was "way back" but it doesn't seem to be an issue anymore but hey... something to try.
try a full url
using https?
try sticking the image somewhere else in your program and see what happens.
try adding this to your HTML (put your website in place of mine - lookup BASE href on google for more info)
<BASE href="http://perrycs/" />
Make sure the image isn't hidden behind a layer (I know it works in some browsers)
tell us the website so we can check it out and get more info to help you in debugging this, seeing context (surrounding code) helps...
Given that it works in other browsers, searching on this topic it seems that often the problem is how IE caches images (ref. Epascarello's comment). Your code is the same as what I have - it works fine except in IE10.
I too, faced this conundrum. Then discovered that it works in 'Page Inspector', so after some digging discovered that (in Internet Explorer) by going to Tools.Internet Options.Advanced
uncheck the 'Disable script debugging (Internet Explorer)' and the one below it.
I found that with IE9 after changing an image.src with
var strVar="C:Users/x/Desktop/caution.png"
image.src=strVar
and calling an alert(image.src) I would get something like this n the alertbox:
file:///C:Users/x/Desktop/"C:Users/x/Desktop/caution.png"
So I tried
image.src=strVar.replace(/\"/g,"")
to remove qoutemarks
and it worked!
alert(image.src)
file:///C:Users/x/Desktop/caution.png

Controls are not working when I have several google maps on one page (in chrome, safari and ie)

I have a page that displays a list of locations chosen by the user, and for each location it also shows the map with a marker pointing to the address.
Everything works fine in firefox and opera, but in safari, chrome and ie the controls (zoom, move, the map options, the scale) are only displayed in one or two maps on the page (usually only the last map). For the others, there's just an image of the map with the marker (and I also can't move the map by dragging it, it's just like a static image).
I checked and it is not a z-index (or another type of css) problem, the controls are not hidden. The div which is supposed to hold the controls is empty.
The code for each map is something like this:
var map_x = null;
if (GBrowserIsCompatible()) {
var mapObjx = document.getElementById("mapx");
if (mapObjx != "undefined" && mapObjx != null) {
map_x = new GMap2(document.getElementById("mapx"));
map_x.setCenter(new GLatLng(40.728444, -73.992117), 14, G_NORMAL_MAP);
map_x.addControl(new GLargeMapControl());
map_x.addControl(new GMapTypeControl());
var point = new GLatLng(40.7284440,-73.9921169);
var marker = createMarker(point,"","<div id=\"gmapmarker\"><\/div>", 0,"");
map_x.addOverlay(marker);
}
} else {
alert("Sorry, the Google Maps API is not compatible with this browser.");
}
where x (in map_x, mapObjx and mapx) is a unique number for each map.
I have tried a lot of things, it seems that causing a slight delay in the code before each new map is added is improving the number of working maps, but never past 3 or 4 (also, this is not really a solution, since there could be many maps on the page, and this would cause it to load too slowly).
As I've said, it only works in firefox and opera. Does anybody have any ideas I could try?
Well, this feels silly. The external scripts included on the page are generated by php, and the script from maps.google.com was included twice. After I corrected this, everything seems to work fine in all browsers.

shift-reload in FF gives unexpected results

I'm presenting a simple animation using img.src replace and the <canvas> tag. At present it's only expected to work in FireFox (FF 3.5.3, Mac OS X 10.5.5), so cross-browser compatibility isn't (yet) an issue.
When the page is first loaded, or loaded into an new window or tab, all seems to work as expected, and the cache behavior on a simple reload does not seem to be an issue; however, if I try to force a reload with shift-reload, I get a problem. Even though the images have been pre-loaded, the preloaded images for the animation don't seem to be available to the browser which then tries to load each new img.src from the server.
Am I looking at a browser bug here, or is there something buggy in my code that I can't see? This is my first shot at implementing a js class, so there might be a lot here that I don't understand.
Any insight from the assembled wise here would be welcome. You can see what I'm talking about at:
http://neolography.com/staging/mrfm/spin-sim.html
Thanks,
Jon
When you shift reload you're telling the browser to reload - not from the cache.
So it shouldn't be a surprise that you're getting the images from the server.
Images can be preloaded in javascript with the following code:
img = new Image();
img.src = "your/image/path";
If you want the images loaded before you use them that might help.
I had a look at your code and you have the following in document.ready()
function countLoadedImages() {
loadedImgs++;
if (loadedImgs == images.length){
$("#loading-image").hide();
$("#controls").fadeIn(100);
}
}
animation = new simAnim("snap", "stripchart", 800, deriveFrameData(spindata));
the animation = new simAnim line is executed regardless if all 100 images are loaded or not...
One possibility to fix this would be to move that line inside the countLoadedImages function like so:
function countLoadedImages() {
loadedImgs++;
if (loadedImgs == images.length){
$("#loading-image").hide();
$("#controls").fadeIn(100);
animation = new simAnim("snap", "stripchart", 800, deriveFrameData(spindata));
}
}
this way that function will be executed once all the images have loaded
Thanks to ekhaled, who tried. I'm now satisfied that this is a browser bug:
Mozilla bug #504184
I have a stripped down example at http://neolography.com/staging/shift-reload/shift-reload-testcase.html which I will leave up. I encourage all to vote for this bug in the mozilla bug tracker so that it will get fixed.
j

Categories

Resources