I've got a page containing a lot of images, which are initially hidden from view as I'm using tabbed divs (ie. hiding some divs using CSS display:none).
Therefore, when then page loads, it takes ages to load all of the images, which looks like the page is slow (as the loading bar on the browser doesn't complete for 10+ seconds).
I would like a way of not loading images until they are visible on the page.
I've played around with jQuery LazyLoad, however this only seems to load images when scrolling the browser (which doesn't work for tabbed divs).
Therefore, is there a way of changing LazyLoad to work like this, or is there a better way of doing this?
Thanks!
Maybe jQuery Tabs could do what you need, with ajax call on tabs...
How do you display your hidden divs?
One plan of attack:
Instead of putting the image URL in the src attribute of the img tag, put it somewhere else (e.g. a hidden span with a particular class above it) and when showing the div, iterate through all the img tags and set the src to the URL it should have had.
As a method it's definitely got some downsides.
If you're using (or can use) the HTML5 doctype, you can use the "data-" prefix for tag attributes:
<img src="" data-src="/path/to/image" style="display: none" />
And then you can use Javascript to fill the src with the data-src:
$(SELECTOR).attr("src", $(SELECTOR).attr("data-src"));
If your only goal is to 'hide' the progress bar which is taking so long due to the large number of images, I'd go for some kind of AJAX solution, since that way the progress bar is not 'used'. It does introduce more complexity in the way you want to load your HTML elements (and possibly when).
I personally don't like using HTML attributes for anything other than their original purpose, so storing the path in another attribute and switching when needed would not be my first option. Instead, I'd try to create a JavaScript array (id => path) and update the separate HTML IMG elements when needed.
Good luck! ;)
I have tried that lately and have to say that this is not possible with js anymore. Maybe it has never been...
Projects like lazyload have always proclaimed that they would stop all images from loading on startup, but you can see in firebug that this does not work. The images are even loaded twice, on domready and when you start scrolling...
Your only choices would be ajax on the on hand or doing something like this:
<img src="transparent.gif" alt="" rel="real image source" />
and then switch attributes when the divs become visible, so the image starts loading.
This works fine as well at least if you don't need google indexing them.
Hope that helps! :)
Edit: Hm, why did I get a -1 when I was just givin an answer? Just have a look at pages with lazyload and enable firebug and then scroll the page. It was even said here on stackoverflow and in the comments for the lazyload plugin that this is the only solution at the moment ... :(
I was unaware of this previously, but LazyLoad does support triggering from events:
http://www.appelsiini.net/projects/lazyload
If anyone needs a hand on how I did this, let me know!
Related
HTML:
<div id="rb-hero" class="rb-hero uk-block uk-flex uk-flex-middle uk-contrast arrowed">
<ul class="uk-slideshow uk-slideshow-fullscreen" id="biggie_slides" data-uk-slideshow="{pauseOnHover: false, autoplay:true}">
<li><img src="{theUrlMedium}" alt="{theAltText}" srcset="{theUrlSmall} 750w, {theUrlMedium} 1200w, {theUrlLarge} 2000w, {theUrlXL} 3000w" ></li>
</ul>
</div>
jQuery:
$('#rb-hero li img').each(function() {
var theSrc = $(this).prop('currentSrc');
// console.log(theSrc);
$(this).prev('div').attr('style', 'background-image: url( '+theSrc+' )');
});
UIKit provides a slideshow function, and I have it in use and it works just fine. The way it works is to use each image slide's src as an inline background-image style attribute on a dynamically-created div. All works fine.
The problem is that UIKit does not use the appropriately-sized image from the provided srcset (which is also working correctly per the currentSrc info in devtools), it simply grabs the fallback img src and thus a pretty high-res image when on mobile.
I'm trying to loop through the elements and replace the inline style's background-imagesource with the currentSrc, but I'm hitting a wall.
The each() method is doing its magic and the console logs the smaller-sized image based on the appropriate srcset source at smaller screens, but the setting of the inline style is going nowhere.
So I'm missing something, and it's probably going to be obvious and glaring but in addition to sleep I need an assist.
Thanks.
Edit: Updated code to a better working place and now only the final bit's not working.
I edited my first answer as it was complete nonsense.
I did some testing with your code and two differently sized images and found that it actually works, but only if certain conditions are met:
I noticed that the browser won't load a smaller sized image from the srcset if there's a larger one already in the cache. I guess it's meant to work this way, but you'll have to keep that in mind and clear the browser cache while testing.
But if you first resize your browser window, then clear the cache and reload the page, the smaller images actually are being loaded and set as background images. I also had to wrap your code in a setTimeout function, otherwise even the console.log was empty and nothing happened. This wasn't necessary with an enlarged browser window (probably because it loaded the image straight from the src tag so there was no delay).
Another problem is that uikit will have set the background image from the src tag and the browser will have loaded it before you set the image url from the srcset, so you'll load both files (which is even worse than only loading the large one on a small screen).
The cleanest and easiest solution would be to modify uikit's slideshow component. They only had to change the part where the image url is read from attr('src') to prop('currentSrc').
I want to load the content of a div on the mouseover of an icon within the div. Furthermore, the mouseover should only fire once and preferably the icon should disappear after loading the content.
The content that will be loaded in de div will be an external file with social media buttons. In case you are wondering; I don't want them to load with the rest of the page because they slow it down. Also, some visitors might not be comfortable with sites like FB and G+ tracking their internet movement.
So, I have gathered some code and copy pasted a bit and this is what I came up with:
<div id="social_media">
<img src="icon.png" onmouseover="javascript:$('#social_media').load('external_file.php'); this.onmouseover=null;" alt="Show Social Media Buttons!" />
</div>
The thing is, it works perfectly fine :) But since it is code that I got from 3 different sources and pasted together, my question is if it's any good? For example, I never tried to find a way to remove the icon on mouseover, it just did :)
I have almost no experience in coding Javscript/jQuery, so please let me know what you think about it so that I can learn from it!
Thanks and greetings from Amsterdam!
avoid the inline code try
<div id="social_media">
<img src="icon.png" alt="Show Social Media Buttons!" />
</div>
attach a mouseenter event handler to the img
$(function(){// short cut of $(document).ready(); read more on google
$("#social_media>img").bind({
mouseenter:function(e){
$('#social_media').load('external_file.php');
}
});
});
P.S the selectors are not optimized nor the outcome of this code it was just to give you an idea
DEMO
The answer to your real question is "the code is kinda middling." The reason the icon went away is because when you called load you replaced it. Internally your document is a tree of piece of the document called the DOM, for "document object model" -- abusing terminology, since that tree is actually an expression of the model, not the model itself.
There's a node in that tree that is your div, and it contains a node with the icon img. When you do the load(), that node is replaced with what you loaded.
As #john says, it's undesirable to put code like that inline, because when you want to figure out what it's doing later, it can be hard to find.
Several things to note:
You really should avoid inline JavaScript code in HTML, that's not clean at all. Move it to an external JavaScript file of possible, or, at least, in a separate <script> tag. It will be ways easier to maintain.
Using this method to fire the event only once seems odd. You should use the jQuery one method, which is made exactly for that.
The icon just disappears because the load method replaces the content of the div in which the icon is.
For example, IMO, the code should be:
$('#social_media').one('mouseover', function(){
$(this).load('external_file.php');
});
I want to be able to change a url directory for, e.g. the first <img> in a <div>, or, any image that is not the first.
My reason is that the loading speed is too slow. That's because I used CSS to generate thumbnails from larger images. I now want to redirect those thumbnail images to a thumbnail folder with small images, rather than having to redirect them individually, which would be a pain.
<img src="images/stories/Images_for_Web/baths_windowToTheSoul_WB4_p90.jpg">
<img src="images/stories/Thumbs/baths_windowToTheSoul_WB4_p90.jpg">
here is the link to the site I'm working on: http://www.d1187169-1.cp.blacknight.com/whitebook1/
I have the CSS automatically resizing and cropping the images for any that is not the first. I like that solution as it will save work in the future so if this part could work also, it would be brilliant, unfortunately I just know CSS, HTML, a little Joomla and only starting in javascript etc., but I am willing to try anything to get this to work!
Any thoughts or suggestions much appreciated. Thanks, Paul
If you were to use jQuery, you could do the following:
$("#somediv img:first").attr("src", "images/new/location");
As you can see just one line of code thanks to the CSS-like selectors. I highly recommend using jQuery for such tasks.
Thumbnails should be generated with php/on the server side. Resizing with CSS is not really resizing - still the full image is loaded.
Maybe you should look in jQuery - it has selectors that are like CSS selectors.
I have a website that displays a list of around 20 auto-played slideshows(each containing 4-5 images) in a page. Now the problem is that this is taking up a long time to load the website(& ofcourse it would, since so many images) but I am wanting to preferentially load all the neccessary css and js files at first, so that the other components on the page are properly rendered before the images begin to download.
So... Is there a way to set a preferential order of loading of the requested resources ?
Is there a way to set a preferential order of loading of the requested resources
Yes - put them in that order in your HTML file!
I am wanting to preferentially load all the neccessary css and js files at first, so that the other components on the page are properly rendered before the images begin to download.
That's a different problem.
Your page components cannot be properly rendered until the dimensions of most elements are known. So, if you have other images in your page layout, those need to get loaded first, or have their width and height attributes specified in the markup.
Since your slideshow images would be mixed in with the rest of your layout if you used pure HTML to load them it sounds like you have little choice but to instead load all of your slide show images from Javascript, per other comments and answers.
Better way then using the dom to create elements have your divs or even img tags src be blank then load them with the images you want in an onload function using innerHTML:
function images(){
var place_to_put_image = document.getElementById("image_div");
place_to_put_image.innerHTML = "<img src=\"your_image_here\"></img>";
}
<body onload="images()>
<div id="image_div></div>
</body>
you could put your images in an array and assign the innerHTML of the div or whatever to the array as well if you want them all in the same place or you could put the onload in div or where ever you want the images to load.
There a few ways you can go about doing it but they all involve not actually putting the images in the HTML - at least not correctly. One way that I like to do it is to add the image src URLs to another property like the alt (not great for accessibility) or rel. Also, give all the images a class that will be used to hook into it with JS.
<img alt="images/foo.jpg" class="loadlater" />
Then in your JS, get all elements with class="loadlater" and set the source to the alt value.
img.src = img.alt;
You didnt mention jQuery. If you were using jQuery, the command to swap the attributes would look like this:
$('.loadlater').each(function() { this.src=this.alt; });
Then, wherever and whenever you call this, the images will be loaded. You will want to call it after your css and js finishes loading - probably the document.load function. Again, if you were using jQuery, it would look like this:
$(function()
{
$('.loadlater').each(function() { this.src=this.alt; });
});
I threw together a quick little microsite that you can see at http://monterraauction.com. If you don't have a super-fast connection (and nothing's cached), the very last items to load are the background-images that are used for CSS image-text replacement (primarily, that h1#head at the top, with a 7kb background image). Nothing debilitating, but it looks slightly awkward. And I'm asking this question as a matter of curiosity more than anything else ;) Also, please note that this occurs in Firefox, but not Chrome.
Now, underneath the h1#head I have a jquery.cycle.lite-powered slideshow in div#photo. In the HTML markup there are a total of 13, heavy image files that make up each of the slides. If I remove all but the first slide, then the problem goes away! So the CSS background-images are loading after...those HTML images are done? But here's what's confusing:
I check it out in YSlow...the CSS background-images have a much lower response time than all of the slides in #photo. Right after all the JS files finish loading, in fact. So why aren't they showing up first?
I tried $('#photo img:last-child').load(function() { alert('Locked and Loaded!')});, but the background-images pop up a while before the alert does, so I'm assuming it's not waiting until the last slide has loaded (admittedly I'm a bit of JS noob so maybe I'm just making a wrong assumption).
I also tried commenting out all the jquery.cycle.lite stuff, so that I knew I didn't have any JS manipulating the DOM elements in #photo, but that wasn't the problem. I tried putting all the JS at the bottom of the document, right before </body>, but that didn't work. Lastly, I tried turning off javascript, and of course the css background-image loads way before the images in #photo, so it's definitely a JS thing (amirite?)
I guess the obvious solution here is to mark the slides up as LINKS rather than IMGs, and have Javascript insert those 12 extra slideshow images after the DOM is ready--users without javascript shouldn't need to download the extra images anyways. But again, I'm curious:
Why does removing the extra HTML images from within #photo solve the problem? And why are the CSS background-images showing up after the HTML images have loaded, even though YSlow says the css background-images loaded first? Seeing as how it happens in FF but not Chrome, is it simply a browser issue?
I appreciate any insight you guys could give me!
What happens if you insert a little script block up at the top of the <head> to pre-load your background images? (Just create new "Image" objects and set the source properties.) I'm not saying that's necessarily a good idea, but it might be an interesting experiment.
(Note that I mean a script block that you intend to be executed at parse time, and not something that sets up a "page ready" handler a la jQuery(function() { ... }).)
Well, I didn't see this issue, even though when I looked at the HTML, all of the <img>s were there. Here's the Net panel for my attempt to reproduce:
http://www.freepichosting.com/graphic/thumbs/322782-2010-04-02-th.png