I've got this setup:
<div id="container1">
<!-- content from one section -->
</div>
<div id="container2" style="display:none;">
<div id="sub-container">
<img src="image1.png" />
<img src="image2.png" />
<!-- 20 or so images sit here -->
</div>
</div>
container1 is initially displayed. On document.ready, all but the first four images are hidden away in order to build a carousel of sorts.
The user clicks a button, container1 fades out and container2 fades in.
The first time the user clicks the button, container2 doesn't fade in, instead it jumps straight to visible. The second time, fade in works as normal.
The images involved are pretty substantial (~10MB total size) but that hasn't been an issue so far as the page is meant to be viewed locally. The fact that the issue doesn't appear if I've got one or two images tells me the browser is struggling to both load the images and fade in at the same time. The second time it loads, the images have been cached and fade in as normal.
I tried a form of preloading like so:
/* take the div outside the viewport but still render it */
.hide {
position: absolute;
top: -9999px;
left: -9999px;
}
var cacheContainer = "<div class='hide'></div>",
$images = $("#sub-container img");
// move the images to the container
$(cacheContainer).appendTo("body").append($images);
// hopefully 500ms would be enough for the images to render?
setTimeout(function () {
images.appendTo("#sub-container");
doGallery(); // build carousel
},500);
... this however leads to the same issue - container2 pops in instead of fading the first time round, and works perfectly fine afterwards.
Any ideas?
As requested, here's what I use to hide/show the containers:
$(document).ready(function() {
var $currentTab = $("#container1"),
$newTab,
newTabName;
// a couple of more unrelated setting up functions go here
doImageCaching(); // the function I've got above
$("#container2").hide();
$("#tab-links>a").click(function(e) {
e.preventDefault();
// probably a bit cheeky doing it this way but oh well
newTabName = $(this).attr("id").replace("-btn", "");
if($currentTab.attr("id") === newTabName) {
return;
}
$newTab = $("#" + newTabName);
$newTab.stop(true, true).fadeToggle(200);
$currentTab.stop(true, true).delay(100).fadeToggle(200);
$currentTab = $newTab;
$newTab = null;
});
});
Here's #tab-links for reference:
<div id="tab-links">
<a id="container1-btn" href="#">show container 1</a>
<a id="container2-btn" href="#">show container 2</a>
</div>
Edit 2 So I just noticed something new: so the second time I switch to container2 it fades in as normal. If I wait 10 seconds or so, and then try and switch to container2 again, the problem reappears.
So it seems to me loading the DOM has nothing to do with this, and I'm dealing with Chrome's internal memory. So it loads the images, and then "forgets" about them when they hide again. Yikes.
Does anyone have any ideas as to how to keep the browser from "forgetting" the images, or is that a direction I shouldn't really take?
So I ended up converting my ultra-high quality PNGs to ultra-high quality JPGs - this led to an approximately 20-30% reduction in file size with barely any reduction in apparent quality. My problem disappeared, too.
The moral of the story is: even if you're developing a page that isn't going online, you still need to optimize your images.
Thank you all for your help.
Related
So I have 2 gifs that are 3s long. One of them is looped from the start, and other gif goes on top of the first one to make a seamless transition.
But to be able to have a seamless transition, I need to somehow know when the first gif ends.
One of the first ideas that I had, is using sprites, but the giant size that it would make is impossible.
Also because the button pressing is random using setTimeout function wouldn't really help?
https://codepen.io/redgreentuoli/pen/gOYxWyo
<img src="Comp_9.gif">
<div class="alt2" >
<img src="Comp_7.gif">
</div>...
$( ".btn1" ).click(function() {
$('.alt2').addClass('alt3');
setTimeout(function(){
$('.alt2').removeClass('alt3');
},3000); //just so it goes baack to origin
});
I'd like to make GIF's only starting to play once they are actually on the screen. I came up with a small JS Script that basically replaces a static image (the first frame of the gif) with the actual gif, as soon as the image is on the monitor.
I can't really change that much in the HTML section since i'm working in a CMS.
HTML:
<div class="lazy">
<img src="firstframe.png">
<img src="gif.gif">
</div>
JS:
var lazies = $('.lazy');
lazies.each(function(){
var src = $(this).find('img').eq(1).attr('src');
if($(this)[0].offsetTop <= window.innerHeight && !$(this).hasClass('lazyactive')){
$(this).find('img').eq(0).attr('src', src);
$(this).find('img').eq(1).hide();
$(this).addClass('lazyactive');
}
})
window.onscroll = function(){
lazies.each(function(i){
if(window.pageYOffset + window.innerHeight >= $(this)[0].offsetTop && !$(this).hasClass('lazyactive')){
var src = $(this).find('img').eq(1).attr('src')
$(this).addClass('lazyactive');
$(this).find('img').eq(0).attr('src', src);
$(this).find('img').eq(1).hide();
}
})
}
The code works fine as long as i have different GIF's on the page.
But as soon as i have the same GIF multiple times on the page, i have a problem. Every time one of the PNG get's replaced with the GIF (by scrolling down), every GIF starts to play from beginning.
I'm not sure if that's normal behaviour of the browsers or the error is in my script..
I am using [this] pre-loader for my personal portfolio.
var h = window.innerHeight;
$('.page-overlay').css('height',h);
var al = 0;
function progressSim(){
document.querySelector('.page-overlay>.text>p').innerHTML =
al+'%';
if(al>=100){
clearTimeout(sim);
}
al++;
}
var sim = setInterval(progressSim,50);
$('.body, .navbar').hide();
setTimeout(function(){
$('.page-overlay').hide();
$('.body,.navbar').show();
},5500);
HTML is like this:
<body>
<div class="page-overlay">
<div class="text"><p></p></div>
<div class="paper-progress-bar"></div>
</div>
<! header, followed by container divs and loads of paragraphs>
</body>
Also, the script is before the closing tag of the body. The animation works fine, it goes from zero to hundred on the page overlay then it shows the body beneath it. But there are two problems here:
I am not sure if this script is actually waiting for the body to load. Note that I am right now coding on local and I don't know if there is any other way to test this. When the website goes live, will this script actually show the percentage of page load? or is it just a simulation or wait time?
I've added the ('.body, .navbar').hide(); but it doesn't work. To add to the gimmick I've set the page-overlay to fixed position with z-index set to high. But the scroll bar is active and the body behind also active while the page is loading. If I am setting the body class display to none it's hiding everything including the page-overlay.
Any help would be appreciated. Thanks in advance. This is my first question on stackoverflow and first time building a website so apologies for any mistakes in question.
p.p.s. I'm using this as preloader https://codepen.io/sanjay8bisht/pen/wKPqVd
I'll start from the second question. The body and navbar hide doesn't work, because you added a "." before the body string.
And the first question:
If we explore the script:
get the window's height.
var h = window.innerHeight;
set the overlay over the page with the height of the page height
$('.page-overlay').css('height',h);
create a variable for keeping the 0 to 100 counter:
var al = 0;
create a function which simulates the page load, later we'll use it
function progressSim(){
show the load counter in a paragraph element on the overlay
document.querySelector('.page-overlay>.text>p').innerHTML = al+'%';
if the value reaches 100 or overrides 100:
if(al>=100){
stop the loop function.
clearTimeout(sim);
}
increase the page load counter.
al++;
finish the function.
}
Now the real part:
repeat the above function with 50 milliseconds interval, so counting from 0 to 100 would take: 50 * 100 : 5000 milliseconds (5 seconds).
var sim = setInterval(progressSim,50);
at the same time, hide the body and the navbar:
$('.body, .navbar').hide();
then after 5500ms (5.5secs) elapses, hide the overlay, and show the body and navbar again.
setTimeout(function(){
$('.page-overlay').hide();
$('.body,.navbar').show();
},5500);
What do you think? It's just an animation. Not a real loader.
You may look at this one: http://github.hubspot.com/pace/docs/welcome/ for something more reliable.
I need to pop up a whole background on click.
It could be done something like an image on the center of page making a whole website less visible and changing after few secs to other image or covering whole web page with my image transforming after few second to next whole web page image. After click everything back to normal.
<div id="right_center"><img style="cursor: pointer;" onclick='knee_fun()' id="iImg" src="img/knee.png" ></div>
<script>
var time = 3000;
var picNo = 0;
var pics = new Array
(
'img/urazy_1.png',
'img/urazy_2.png',
'img/empty.png'
);
function knee_fun()
{
document.getElementById('iImg').src = pics[picNo++];
if (picNo >1 ) picNo =2;
setTimeout('knee_fun()', time);
clearTimeout('knee_fun()');
}
</script>
I made this= cycling 2 images but how to position it on the center of the page and not reorganizing whole page? I need also to make less visible all the page content during this images cycle. (it should end after click).
Other option is to make a images cycle which contains full page but it need to cover whole web page. and after click back to normal.
ow in addition how to add second function with parametr?
<div id="zoom" onClick="document.getElementById('song').play()">
<audio id="song" src="nanana.mp3"></audio>
</div>
when i add: onclick="doc~(); injuries_change();" id="iImg"> second isnt working
Thanks for looking, I have this plan, I want to create a gallery where I have the main image which is changed by mouse-ing over a bunch of 8 thumbnails, easy.
What I would like to add is separate small bunch of 3 thumbnails and when these are moused over they change the 8 thumbnail images and make them call up 8 new main images. Sorry I hope that’s understandable?
So it’s a little like a tiered or a nested arrangement almost like a small folder tree where the new 3 thumbs hold different libraries of 8 thumbs… no that’s probably just made it even more confusing!!!..
I was keen that it was all done with mouse over the thumbs so it’s smooth and there’s no clicking or reloading the page.
I’ve had a good look around but probably just need telling what terms/phrases/commands to pop in my search engine.
Getting the 3 thumbs to change the 8 thumbs and the main image should be straightforward enough I’m currently using this:
<img src = "images/nicepic5thumb.png" onmouseover =”document.main.src = 'images/nicepic5.jpg';">
Where the main big image is:
<img src = "images/nicepic1.jpg" name= "main">
And I guess it could be expanded to multiple images. Doesn’t have to be done like this however, just whatever would work best, it’s making one mousover change multiple mouseover commands thats currently beyond me.
Ultimately I aim to get all the transitions to fade.
Very grateful for a pointer in the right direction.
I would sent the 3 panels (or more) of 8 thumbs with the respective commands to change main images and make the 3 index thumbs switch the visibility of the 8 images panel
This is actually something that would be very easy to do in jQuery
All you need to do is add a common class to the images in the gallery or more efficiently add an ID to the element that contains the image and use that to select the images such as.
<img src = "images/nicepic1.jpg" name= "main" id="main_img">
<div id="gallery"><img src="nicepic1thumb.png"><img src="nicepic2thumb.png"><img src="nicepic3thumb.png"></div>
<script>
$(document).ready(function(){
$("#gallery img").onmouseover(function(){
$("#main_img").attr('src',$(this).attr('src').replace("thumb.png",".jpg"));
}
}
</script>
Here is a full working gallery without animations that does exactly what you wanted.
<html>
<head>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript" ></script>
<script>
$(document).ready(function(){
gallery.init();
});
var gallery = {
main_img: null,
init:function(){
gallery.main_img = $("#main_img img");
$("#images img").click(function(){
gallery.change($(this).attr('src'));
});
},
change: function(image){
gallery.main_img.attr('src', image.replace("thumb.png",".jpg"));
}
}
</script>
</head>
<body>
<div id="gallery">
<div id="main_img"><img src="images/image1.jpg"/></div>
<div id="images">
<img src="images/image1thumb.png"/><img src="images/image2thumb.png"/><img src="images/image3thumb.png"/><img src="images/image4thumb.png"/><img src="images/image5thumb.png"/>
</div>
</div>
<body>
</html>
If you need animations such as fading and stuff just ask.