I have a gallery plugin that generates HTML. I need to somehow wait until the appended html has finished loading it's assets to append it again. I tried window.load but that didn't work. The only thing working that will modify the the targeted area is a setTimeout callback which I feel is very hacky.
How can I accomplish what I am trying to do?
The current code I am trying to run on the generated markup is:
jQuery('ol').append('<li data-toggle="modal" id="thumb" class="yt-thumb" overflow-scroll="false" overflow-scroll="true" data-target="#youtubeModal"><img src="/images/dome-thumb.jpg" /></li> '); // add youtube to thumb slider
jQuery('ol').appendTo( jQuery('#thumb-area') )
Heres what I would do, I recognize its not perfect but you could insert the image into the dom sepratly with an onload event and when that is called back insert the modal knowing that the browser has completely loaded the image.
$('body').append('<img style="display:none" id="temp">');
$tempImg = $('img#temp');
$tempImg.on('load', function() {
// Append your modal here
jQuery('ol').append('<li data-toggle="modal" id="thumb" class="yt-thumb" overflow-scroll="false" overflow-scroll="true" data-target="#youtubeModal"><img src="/images/dome-thumb.jpg" /></li> '); // add youtube to thumb slider
jQuery('ol').appendTo( jQuery('#thumb-area'))
});
$tempImg.attr('src', '/images/dome-thumb.jpg');
So when you update the src on the hidden temp image the browser will download the image, then when that is finished you insert the modal.
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.
I'm working with Isotope and I have a lot of images in it.
The problem is that when visiting my one page website from a smartphone it takes quite a bit to load the page as isotope load all the images thumbnails as soon as isotope itself loads.
So, basically I want to hide/not load all the images that mustn't be shown if it's category isn't clicked and what I did was use two workarounds:
set the figure to display:none so that it doesn't show the void where it was supposed to be and the other images can actually occupy that space
set the img src to about:blank so that it doesn't load until it's category is clicked
then when the link "Click me!"(category) is clicked the figure gets set to display:block and the img src gets replaced by the real image path.
style:
#showfigure{
display:none; !important
}
body:
Click me!
<figure id="showfigure" class="filter imgtoshow">
<img id="showimg" src="about:blank" alt="">
</figure>
script:
<script>
function showAll() {
document.getElementById("showfigure").style.display = 'block';
$("#showimg").attr("src","example.jpg");
};
</script>
Now, the only way I got it to work with multiple figures/images was giving each figure and image it's own id (showfigure1, showfigure2, showfigure3 etc... and showimg1, showimg2, showimg3, etc...) as using the same id only works for the first figure/img in the code.
Am I missing something?
I tried replacing the path of the img src like this:
http://jsfiddle.net/F6Gds/28/
But I can't get it to do the same with the onclick function from the link "Click me!", and anyways there's the same problem with the ids.
Thanks in advance for any help!
this is Augusto from Italy
when migrating from HTML to XHTML I am facing an unresolved problem
In html code I have an image (bigimg) that is at first charged via Js charged by the body onload, then other images, out of a preview series, are being charged, thus replacing my image,
In body:
<body onload="...........;viewimgac('images/accessories/img01cs.jpg');...............">
The function is:
// the waiting image view and the main image loading is managed
function elaboraimgac(urlimg) {
document.getElementById('dattesa').style.filter = "alpha(opacity:"+90+")";
document.getElementById('dattesa').style.MozOpacity = 90/100;
document.getElementById('dattesa').style.KHTMLOpacity = 90/100;
document.getElementById('dattesa').style.opacity = 90/100;
MM_changeProp('dattesa','','style.visibility','visible','LAYER'); // div is made visible through the waiting gift.
document.getElementById('bigimgid').src = urlimg; // I load the image
The code page shows:
<img src="#" id="bigimgid" style="position:absolute;left:0px;top:0px;" onload="finecaricimg()" alt="" />
the <img> tag, as it is, prevents XHTML validation. I have to eliminate onload="finecaricimg()", being the function allowing view of image duly placed in the page using the image size that is available after loading.
I acted this way:
1) change <img tag
<img src="#" id="bigimgid" style="position:absolute;left:0px;top:0px;" alt="" />
2) I added :
function elaboraimgac(urlimg) {
//to Js elaboraimgac function
//........
//........
document.getElementById('bigimgid').onload = finecaricimg(); // the specific function is called after loading
}
To intercept the image loading end and recall the loading end function
Unfortunately the procedure is unsuccessful. Via alert I realized that the image size – when the loading end is charged – is zero, as if finecaricimg() is charged right after the .src processing and not when the image loading is over.
I tried to add:
document.getElementById('bigimgid').src = urlimg;alert("AAAAA"); // load image
then, when the alert window appears, I wait for some seconds before clicking OK. This way the image size is correct and the image is properly placed in the page.
I am unable to understand, as the code seems the correct one.
I am therefore asking for your suggestion.
....onload = finecaricimg();
You just called your function immediately and assigned its result to onload (just like any other function call).
You want to assign the function itself, without calling it.
I have solved in this way:
var img = document.getElementById("bigimgid");
img.src = urlimg; // carico l'immagine
img.addEventListener("load", finecaricimg); // a fine caricamento richiamo la funzione specifica
thanks
I have created a simple photo gallery viewer, and I would like to preload the images in the background, and then run a function when they are done.
My question is, how do I do that?
var image = new Image();
image.src = "http://foo.com/myimage.jpg";
//if you have a div on the page that's waiting for this image...
var div = getElementById("imageWrapperDiv");
//you can set it on the image object as the item to draw into...
image.myDiv = div;
image.onload = function(){
//do whatever you're going to do to display the image
//so in this example, because I have set this objects myDiv property to a div on the page
// I can then just populate that div with an img tag.
//it's not the most elegant solution, but you get the idea and can improve upon it easily
this.myDiv.innerHTML = "<img src='" + this.src +"'>";
}
Once the image loads, it's in the browser's cache, so, if you use the src property you can draw it anywhere on the page and it will display instantly.
To preload an image use the <link> tag and add preload to the rel-attribute:
<link rel=preload href=path/to/the/image.jpg as=image>
Alternatively in Javascript:
var preImg = document.createElement('link')
preImg.href = 'path/to/image.jpg'
preImg.rel = 'preload'
preImg.as = 'image'
document.head.appendChild(preImg)
The preload value of the element's rel attribute allows you to
write declarative fetch requests in your HTML , specifying
resources that your pages will need very soon after loading, which you
therefore want to start preloading early in the lifecycle of a page
load, before the browser's main rendering machinery kicks in. This
ensures that they are made available earlier and are less likely to
block the page's first render, leading to performance improvements.
Documentation: https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
I like this CSS method versus the typical Javascript function:
Place this in your CSS file:
div#preload { display: none; }
Place this at the bottom of your HTML document:
<div id="preload">
<img src="http://domain.tld/image-01.png" width="1" height="1" alt="Image 01" />
<img src="http://domain.tld/image-02.png" width="1" height="1" alt="Image 02" />
<img src="http://domain.tld/image-03.png" width="1" height="1" alt="Image 03" />
</div>
This method ensures that your images are preloaded and available for use elsewhere in the document. Just remember to use the same path as the the preloaded images.
http://perishablepress.com/pure-css-better-image-preloading-without-javascript/
I'm running a Javascript replace function to replace standard images with class="replace-2x"on my jQuery Mobile site with Retina-quality images if the user is on a mobile device with Retina display. For example, on a Retina device, logo.png will be replaced with logo#2x.png. The JS function is here:
function highdpi_init() {
$(".replace-2x").each(function () {
var src = $(this).attr("src");
$(this).attr("src", src.replace(".png", "#2x.png").replace(".jpg", "#2x.jpg"));
});
}
$(".page").live('pageinit',function(event){
highdpi_init();
});
I'm now running into an issue where the replace function is running more than once. So for example, it replaces logo.png with logo#2x.png as the page is loading, but then as the page continues to load, it KEEPS replacing .png with #2x.png in the img src over and over so that the image tag ends up looking like this:
<img src="mobile/images/logo#2x#2x#2x#2x#2x#2x#2x#2x#2x#2x#2x.png" class="replace-2x" alt="logo" width="200">
How can I prevent this from replacing on a single img element more than once? Keep in mind, I will have multiple images on the same page, so the function will need to apply to all images, but only one time each.
The problem is surely that your 'pageinit' event is being called more than once. You can either follow MДΓΓ БДLL's idea (which won't work if images are dynamically added) or you can make your handler smarter so that it doesn't replace the src if it already was replaced
function highdpi_init() {
$(".replace-2x").each(function () {
var $this = $(this);
var src = $this.attr("src");
$this.attr("src", src.replace(".png", "#2x.png").replace(".jpg", "#2x.jpg"));
// Remove the class so it doesn't replace it again
$this.removeClass('replace-2x')
});
}
You don't need JS for this, you could do it in CSS only.
<link rel="stylesheet" media="only screen and (-webkit-min-device-pixel-ratio: 2)" href="/css/highdpi.css"/>
You could make your images look like
<img src="transparent.gif" class="logo-a" alt="logo" width="200" />
And in highdpi.css you could do
img.logo-a {
background-image: url('file#2x.png')
}
And in lowdpi.css
img.logo-a {
background-image: url('file.png')
}
Using .one() should work since it is just a binding and if you are using Jquery Mobile the way that is suggested it will be just fine. That is unless you are passing back the html from the server. In which case it would be a good idea to add an extra condition to make sure that the src doesn't already have #2x.png before replacing.
There is disappointingly little documentation on pageinit on the offical jQuery Mobile docs. So I'm going to speculate here. It looks like pageinit is used to fire events for when a specific DOM element has finished loading, since it may not have been loaded on the initial page load (deferred until needed). That being said, it may be that adding/altering images to the DOM element in question fires the pageinit again. Could you tag each updated image with something that says, 'hey, I've already been updated to 2x'? Something such as
$.data(targetimg, 'retinafied', true);
And then check for that value before replacing the src?