I want to load the js first and the images second. Reason: I want the blue rollover affect to be applied immediately. There will eventually be double the images currently on this page so it will eventually be a bigger user experience problem as it grows.
Any ideas?
http://www.rollinleonard.com/elements/
If both your JS and images are linked directly from the HTML (meaning you're using the typical <script type="javascript" src=...> and <image src=...> tags) then the load order is entirely up to the user's web browser (as far as I know).
Your best chance to control the load ordering is to load the JavaScript per usual and then have custom JS to manipulate the DOM to load the images later, e.g.:
var myDiv = document.getElementById("myImageHoldingDiv")
, img = new Image();
img.onload = function() {
myDiv.appendChild(img);
}
img.src = myImageUrl;
Related
I'm creating a loading bar for my website and I want to update the loading progress (%) with each image load. For testing purposes, I used console.log() (instead of updating my loading bar).
I want to detect when each individual image loads. My images are all within <div id='images>
I have not found a solution that has worked after 5 hours of searching. I'm new to jQuery & Javascript, so I may have been using incorrect syntax (such as not targetting the image container correctly, but I'm not sure.
I have tried the imagesloaded jQuery plugin, but when using $('#images').imagesLoaded(), imagesloaded had said that all images had loaded, when they hadn't. (I'm testing using two 4k images so I can see the images slowly load).
The imagesloaded jQuery code I used for testing (loadProgress.js):
$('#images').imagesLoaded() //My images are within "<div id='images></div>"
.always( function( instance ) {
console.log('all images loaded');
})
.done( function( instance ) {
console.log('all images successfully loaded');
})
.fail( function() {
console.log('all images loaded, at least one is broken');
})
.progress( function( instance, image ) {
var result = image.isLoaded ? 'loaded' : 'broken';
console.log( 'image is ' + result + ' for ' + image.img.src );
});
// Code I used to keep track of when the page actually loaded
console.log('Page load started')
window.onload = function() {
console.log('Page load complete')
My HTML (Images were for testing purposes only and may be copyright) [just a snippit, not including doctype, body etc]:
<script src="https://unpkg.com/imagesloaded#4/imagesloaded.pkgd.min.js"></script>
<script scr="loadProgress.js"></script>
<div style="text-align:center" id="images">
<img src="https://wallpapers.gg/wp-content/uploads/2018/01/Old-Lion-4K.jpg" alt="Lion 4K" id='image' />
<img src="https://images7.alphacoders.com/383/383230.jpg" alt="Lion 4K" id="image" />
</div>
Console output [comment]:
Page load started
all images loaded
all images successfully loaded
[a good 5 second delay]
Page load complete
The output looks promising as the images are said to load after the page load has begun, but there is a 5 second delay between all images successfully loaded and Page load complete where I can see the images slowly render top-to-bottom and can also see the spinning loading icon in my browser tab (indicating that the images have not loaded yet, as there is no other html to load). I believe that the plugin is not correctly detecting the images container.
How can I (preferably automatically, not having to assing a unique ID to each image, and for them to collectively be found) detect when each individual image has loaded?
I'd like my console output to be (for example with two images):
Page load started
Image loaded
Image loaded
[no delay]
Page load complete
I am not looking to detect when all images have been loaded, and specifically want to repeat an action each time an image is loaded. In this case, the action would be console.log('Image loaded')
Using either Javascript or jQuery isn't a problem, and if you know a plugin which can achieve this more efficiently, I'd love to know.
I am not sure about the jQuery plugin you are using, but you could register an "onload" function to each image you want to load. No additional plugins/libraries needed, plain JavaScript should be fine.
Ideally, you would do it on backend side, not frontend, since images might be already loaded (think of browser cache) at the moment you assign the "onload" function.
If you want to target every image, just use the $('img') as your selector. If not, target their container element an you should be good to go.
Using javascript, I am adding many pixel images, by moving <image id="myimage" xlink:href="mysource.png" ... /> elements from an XMLdoc to the DOM of an SVG image in a loop, like so
var elems = this.XMLdoc.getElementsByTagName('image');
var elem = elems.item(0);
svg.appendChild(elem);
Sometimes not all of the images are completely loaded, due to network problems, or server limitations.
After loading all images, I would like to check whether that has been successful and, if not, reload the pixel image mysource.png.
I could remove and add back all <image> tags and rely on that the cached images are loaded successfully, but then I would still not know if all images were loaded in the second round.
If it was included with <img> in html, I would do this by checking image.complete, but that does not seem to work for the SVG images.
I am also using Snap.svg to manipulate the SVG. A solution based on this library would be convenient if it can help.
In SVG you listen to the load event through the load event, you can do it like this:
var elems = this.XMLdoc.getElementsByTagName('image');
var elem = elems.item(0);
elem.addEventListener("error", replaceImage);
svg.appendChild(elem);
function replaceImage(e){
var parent = this.parentNode;
var newImage = this.cloneNode();
newImage.addEventListener("error", replaceImage);
parent.removeChild(this);
parent.appendChild(newImage);
}
I'm making a Chrome extension which in order to reduce bandwidth usage it stops all outcoming requests which are images.
I want to provide functionality where if the user clicks on the image (or technically a layer on top of that image) it would try to reload the image, this time not being blocked by the extension.
How can I tell the browser to retry loading the image? And if there isn't a straightforward way to do it, what would be a work around? Deleting the old image from the DOM and adding it again?
Any help is appreciated. :)
EDIT 1:
To answer #CBroe's question:
Using the chrome.webRequest.onBeforeRequest API in a background script.
To answer #jfriend00's question:
The usual placeholder "couldn't load image" icon, I guess also known as "broken file" icon:
See all those broken images?
That screenshot also illustrates the point of a layer on top of another image. Should those images not be broken, the loaded image would be there but that layer (the one in a dark grey which shows the image's dimensions) still remains there.
The desired href still exists there in the img tag:
If simply assigning the same src value to the img element is not enough¹, then create a new Image object in JavaScript, and assign the value to its src property.
¹ It might not be, if the browser just goes, “oh hey, that is the same value for the src attribute that the img already had, so I don’t have to do anything” – creating a new JS Image object however should make the browser request that resource again if he realizes he does not have it cached already.
What I would do instead is replace the URLs of the images with an image from your extension. A 1x1 pixel transparent GIF or PNG.
When you do this, add an attribute to all of the elements you replaced... something like data-yourextension-originalurl, with the URL of the original image. If the user then wants to load images, it's easy enough to go back and fix those image elements.
While I'm not too familiar with the Chrome API, a quick glance seems to suggest that there's no way to get the specific img element from each onBeforeRequest, which you'd need to know in order to figure out where to attach custom code.
This may be better accomplished with native JavaScript of some sort. For example, if Chrome lets you inject code on load, you could apply a function like the one below to all img elements after document load but before image load.
// Given an img element, replaces its src with a placeholder URL,
// and sets its click action to load its original src
function makePlaceholder(elem){
elem["data-oldtitle"] = elem.title;
elem["data-oldhref"] = elem.href;
elem["data-oldsrc"] = elem.src;
elem["data-oldonclick"] = elem.onClick;
elem.title = "Click to load the blocked image.";
elem.href = '';
elem.src = "http://example.com/placeholder.png";
elem.onClick = function(){
this.src = this["data-oldsrc"];
this.title = this["data-oldtitle"];
this.href = this["data-oldhref"];
this.onClick = this["data-oldonclick"];
};
}
The simple way to force reloading an image in JavaScript is:
var img = document.getElementById("myImage");
img.src = img.src.replace(/\?.+/,"") + "?" + new Date().getTime();
This adds a unique QueryString to the image which basically forces the browser to not use a cached version of the image.
I am looking for a way to cancel image loading using javascript. I've looked at other questions and hiding them is not enough. Also, the rest of the page must load (window.stop() is out of the question).
The page that is being loaded is not under my control, only one thing is guaranteed - the first <script> on the page is my javascript (lightweight - no jquery).
I have tried setting all img sources to nothing, that did not help since the dom is created after the page is parsed, and all browsers have the same behavior - the img is loaded once it is parsed.
Not possible with modern browsers. Even if you alter the src attribute of image tag with JavaScript browsers still insist on loading the images. I know this from developing the Lazy Load plugin.
The only way I can see to stop images loading is to not have an src attribute present in the image itself, and using a custom data-* attribute to hold the location of the image:
<img data-src="http://path.to/image.png" />
Obviously this doesn't gracefully degrade for those (admittedly rare) JavaScript disabled browsers, and therefore requires a noscript fall-back:
<img data-src="http://path.to/image.png" />
<noscript><img src="http://path.to/image.png" /></noscript>
And couple this with a simple function to load the images when you, or your users, are ready for them:
/* simple demo */
function imagePopulate(within, attr) {
within = within && within.nodeType == 1 ? within : document;
attr = attr || 'data-src';
var images = within.getElementsByTagName('img');
for (var i = 0, len = images.length; i < len; i++) {
if (images[i].parentNode.tagName.toLowerCase() !== 'noscript') {
images[i].src = images[i].getAttribute(attr);
}
}
}
document.getElementById('addImages').onclick = function(){
imagePopulate();
};
JS Fiddle demo.
I can't be sure for all browsers, but this seems to work in Chrome (in that there's no attempt, from looking at the network tab of the developer tools, to load the noscript-contained img).
It can be done with webworkers. See the following example:
https://github.com/NathanWalker/ng2-image-lazy-load.
Stopping a web worker cancels the image loading in browser
Recalling the onload event:
window.onload=function(){
imgs = document.getElementsByTagName('img');
for(i = 0; i < imgs.length(); i++){
imgs[i].src = '#';
}
};
If you want to only cancel the loading of the image , you can use sємsєм's solution
but i do not think it will work by using an window onload event .
You will probably need to provide a button to cancel the image load. Also i suggest, instead of setting the src attribute to "#" , you can remove the src attribute itself using
removeAttribute()
[Make sure you disable the cache while testing]
You need a proxy.
Your script can redirect to another server using something like
location.replace('http://yourserver.com/rewrite/php?url='+escape(this.href));
perhaps you tell us why you want to cancel image loading and whose site you are loading on so we can come up with a better solution
If there is nothing on the page other than images, you could try
document.write('<base href="http://yourserver.com/" />');
which will mess with all non-absolute src and hrefs on the page.
UPDATE Horrible hack but perhaps this almost pseudo code (I am off to bed) will do someting
document.write('<script src="jquery.js"></script><div id="myDiv"></div><!-'+'-');
$(function() {
$.get(location.href,function(data) {
$("#myDiv").html(data.replace(/src=/g,'xsrc='));
});
})
The closest you can get to what you maybe want is to have a quickly loaded placeholder image (ie. low resolution version of your image) and a hidden image (eg. {display:none}) in which the large image gets loaded but not displayed. Then in the onload event for the large image swap the images over (eg. display:block for the large image display:none for the smaller). I also use an array (with their url), to reuse any images that have already been opened.
BTW if you open an image in a new webpage when it gets closed then the image loading will be cancelled. So maybe you can do something similar in a webpage using an iframe to display the image.
To close the iframe and therefore unload the image, remove the frame from the DOM
(another advantage is that browsers spawn another process to deal with iframes, so the page won't lock up while the image loads)
I have a web page where lots of images called from server using image
scr attribute.
I have created a function like which is triggered by td click.
function GoToStep(stepNo) {
var imgSrc = $("#h1" + stepNo).val();
$(".img_vertical").css("background-image", "url(" + imgSrc + ")");
}
Now the problem is this. For slower connections the images come after some
moment.
Can I pre load images to avoid waiting time when user clicks
td?
I have seen some jquery function to pre load images.
Kindly give some idea how can I achieve it.
Pre-loading an image is equivalent to loading an image but never displaying it. So, you can easily do it like this:
<img src="image.png" alt="" style="display:none;"/>
Now this image will be loaded as soon as the html starts rendering. Whenever you need to use this image as a display or background, just set the address to image.png and it will automatically be fetched from browser's cache.
This can be done using some javascript functions. Quoting from another question.
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);
Explanation of how javascript preloaders work (different question)
[...] The way it works is simply by creating a new Image object and setting
the src of it, the browser is going to go grab the image. We're not
adding this particular image to the browser, but when the time comes
to show the image in the page via whatever method we have setup, the
browser will already have it in its cache and will not go fetch it
again. [...]
So in your case, you should use something like
$(function() {
// Do stuff when DOM is ready
preload([
'img/bg1.jpg',
'img/bg2.jpg',
'img/bg3.jpg'
]);
});