Preload images during scroll - javascript

I am using Jquery to alter the source of an image as the page scrolls. However, currently they are loading as they are displayed and i would like to have them preload several images prior to being shown.
HTML
<img src="/img/1.jpg" />
JQuery
$(window).load(function(){
// Array of images to swap between
var images = [/img/1.jpg, /img/2.jpg, /img/3.jpg, /img/4.jpg];
var totalImages = images.length;
var documentHeight = $(document).height();
// Work out how often we should change image (i.e. how far we scroll between changes)
var scrollInterval = Math.floor(documentHeight / totalImages);
$(document).scroll(function () {
// Which one should we show at this scroll point?
i = Math.floor($(this).scrollTop() / scrollInterval);
// Show the corresponding image from the array
$('img').attr('src', images[i]);
});
});//]]>
css
img {
position: fixed;
top: 0;
left: 0;
height: 100%;
}
body {
height: 5000px;
}
Attempt.
I would like to add something similar to this to,
$(document).scroll(function () {
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
(new Image()).src = this;
});
}
i = Math.floor([i]+'1');
preload([[i]]);
}
But cannot figure how to code it... (New to JS)

Inside your loop.
var nextTenImages = images.slice(i, i+10);
// preload the next image
preload(nextTenImages);
JSFiddle: http://jsfiddle.net/gvee/ygkWH/8/
EDIT: Credit to the following SO topic for preloading images: Preloading images with jQuery

Related

How to load an initial set of images, then animate between them randomly without jQuery

On my page I have a gallery (just a div) with several images on it. I want to show the first 9 images immediately, then load more images and use CSS transitions to animate between the existing images.
Loading the initial images is easy but I do not know the best way to load the next set of images and then start animating (using the CSS Transform property). So far this is what I have:
HTML (abbreviated):
<div id="mainContainer">
<div class="imageHolder"><img class="homeImages" src="test.png"></div>
<div class="imageHolder"><img class="homeImages" src="test1.png"></div>
<div class="imageHolder"><img class="homeImages" src="test3.png"></div>
</div>
CSS (abbreviated):
img {
display: inline;
position: relative;
margin: 0;
padding: 0;
width: 30%;
}
.changed.opaque {
opacity: 0;
border: 2px solid red;
}
I am looking to do a variety of effects, the most simple one would be to change the opacity and fade one image over the other. To load the next set of images I have this:
Javascript:
var imageArray = [
'test2.png',
'test3.png',
'test4.png',
'test5.png',
'test6.png',
];
var imageNodeArray = [];
for(var i = imageArray.length - 1; i >= 0; i -= 1) {
var img = new Image();
img.onload = function() {
imageNodeArray.push(this);
};
img.src = imageArray[i];
}
document.onclick = function() {
imageNodeArray[0].setAttribute('class', 'changed.opaque');
divs[0].appendChild(imageNodeArray[0])
}
This does add an image to my mainContainer however, even though I can tell from devTools that it has the changed.opaque class applied to it, no opacity is shown on the added image.
I am curious about this. I would also like to know the best way to "stack" images to have a bunch to animate through. I am not sure that appending child is right.... Thank you
function animate() {
var index = Math.floor((Math.random() * document.querySelectorAll('#mainContainer > .imageHolder').length + 1));
var current = document.querySelector('.top');
var next = document.querySelector('.imageHolder:nth-of-type(' + index + ')');
current.className = "imageHolder";
next.className += "top";
}
Should be able to handle and switch between any dynamically inserted images.
Currently using:
.imageHolder {
display: none;
}
.top {
display: inherit;
}
to switch the image is just a simple implementation.
Here's the working fiddle: http://jsfiddle.net/e9dxN/1/
Alternative implementation: http://jsfiddle.net/e9dxN/6/

Scroll event background change

I am trying to add a scroll event which will change the background of a div which also acts as the window background (it has 100% width and height). This is as far as I get. I am not so good at jquery. I have seen tutorials with click event listeners. but applying the same concept , like, returning scroll event as false, gets me nowhere. also I saw a tutorial on SO where the person suggest use of array. but I get pretty confused using arrays (mostly due to syntax).
I know about plugins like waypoints.js and skrollr.js which can be used but I need to change around 50-60 (for the illusion of a video being played when scrolled) ... but it wont be feasible.
here is the code im using:-
*
{
border: 2px solid black;
}
#frame
{
background: url('1.jpg') no-repeat;
height: 1000px;
width: 100%;
}
</style>
<script>
$(function(){
for ( i=0; i = $.scrolltop; i++)
{
$("#frame").attr('src', ''+i+'.jpg');
}
});
</script>
<body>
<div id="frame"></div>
</body>
Inside your for loop, you are setting the src attribute of #frame but it is a div not an img.
So, instead of this:
$("#frame").attr('src', ''+i+'.jpg');
Try this:
$("#frame").css('background-image', 'url(' + i + '.jpg)');
To bind a scroll event to a target element with jQuery:
$('#target').scroll(function() {
//do stuff here
});
To bind a scroll event to the window with jQuery:
$(window).scroll(function () {
//do stuff here
});
Here is the documentation for jQuery .scroll().
UPDATE:
If I understand right, here is a working demo on jsFiddle of what you want to achieve.
CSS:
html, body {
min-height: 1200px; /* for testing the scroll bar */
}
div#frame {
display: block;
position: fixed; /* Set this to fixed to lock that element on the position */
width: 300px;
height: 300px;
z-index: -1; /* Keep the bg frame at the bottom of other elements. */
}
Javascript:
$(document).ready(function() {
switchImage();
});
$(window).scroll(function () {
switchImage();
});
//using images from dummyimages.com for demonstration (300px by 300px)
var images = ["http://dummyimage.com/300x300/000000/fff",
"http://dummyimage.com/300x300/ffcc00/000",
"http://dummyimage.com/300x300/ff0000/000",
"http://dummyimage.com/300x300/ff00cc/000",
"http://dummyimage.com/300x300/ccff00/000"
];
//Gets a valid index from the image array using the scroll-y value as a factor.
function switchImage()
{
var sTop = $(window).scrollTop();
var index = sTop > 0 ? $(document).height() / sTop : 0;
index = Math.round(index) % images.length;
//console.log(index);
$("#frame").css('background-image', 'url(' + images[index] + ')');
}
HTML:
<div id="frame"></div>
Further Suggestions:
I suggest you change the background-image of the body, instead of the div. But, if you have to use a div for this; then you better add a resize event-istener to the window and set/update the height of that div with every resize. The reason is; height:100% does not work as expected in any browser.
I've done this before myself and if I were you I wouldn't use the image as a background, instead use a normal "img" tag prepend it to the top of your page use some css to ensure it stays in the back under all of the other elements. This way you could manipulate the size of the image to fit screen width better. I ran into a lot of issues trying to get the background to size correctly.
Html markup:
<body>
<img src="1.jpg" id="img" />
</body>
Script code:
$(function(){
var topPage = 0, count = 0;
$(window).scroll( function() {
topPage = $(document).scrollTop();
if(topPage > 200) {
// function goes here
$('img').attr('src', ++count +'.jpg');
}
});
});
I'm not totally sure if this is what you're trying to do but basically, when the window is scrolled, you assign the value of the distance to the top of the page, then you can run an if statement to see if you are a certain point. After that just simply change run the function you would like to run.
If you want to supply a range you want the image to change from do something like this, so what will happen is this will allow you to run a function only between the specificied range between 200 and 400 which is the distance from the top of the page.
$(function(){
var topPage = 0, count = 0;
$(window).scroll( function() {
topPage = $(document).scrollTop();
if(topPage > 200 && topPage < 400) {
// function goes here
$('#img').attr('src', ++count +'.jpg');
}
});
});

How to change Fancybox preloader image?

I want replace default Fancybox1.3.4 image preloader (fancy_loading.png) with another preloader.
The Fancybox preloader coded not only in css, but also in javascript itself.
Seems, there are two places in javascript, at least:
_animate_loading = function() {
if (!loading.is(':visible')){
clearInterval(loadingTimer);
return;
}
$('div', loading).css('top', (loadingFrame * -40) + 'px');
loadingFrame = (loadingFrame + 1) % 12;
};
and
$.fancybox.showActivity = function() {
clearInterval(loadingTimer);
loading.show();
loadingTimer = setInterval(_animate_loading, 66);
};
$.fancybox.hideActivity = function() {
loading.hide();
};
So customizing the preloader will require modifying javascript too.
How can I change fancybox-1.3.4 javascript to set custom preloader image?
The CSS declaration is here:
#fancybox-loading div {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 480px;
background-image: url('fancybox.png');
}
They are using a sprite for the background image and changing the background-position to animate it. If you're going to use a loading.gif image, then you won't need to animate it.
You need to change the background-image path, height, and width to cater to your new image. You may want to comment out their JS code for the animation so that it doesn't conflict.
The loading div is being declared here:
$('body').append(
tmp = $('<div id="fancybox-tmp"></div>'),
loading = $('<div id="fancybox-loading"><div></div></div>'),
overlay = $('<div id="fancybox-overlay"></div>'),
wrap = $('<div id="fancybox-wrap"></div>')
);
You can either piggyback on the loading variable or simply change the styling on #fancybox-loading. You'll then need to remove any reference to loadingTimer and loadingFrame. Comment out this entire function:
/*_animate_loading = function() {
if (!loading.is(':visible')){
clearInterval(loadingTimer);
return;
}
$('div', loading).css('top', (loadingFrame * -40) + 'px');
loadingFrame = (loadingFrame + 1) % 12;
};*/
Modify the following function:
$.fancybox.showActivity = function() {
//clearInterval(loadingTimer);
loading.show();
//loadingTimer = setInterval(_animate_loading, 66);
};
That should do it. You don't want loading to have any setInterval on it since you won't be animating it, but you do want it to hide/show conditionally.
There are two options -
1) Upgrade to v2 as it is now using animated gif
2) Ĺ–eplace showActivity and hideActivity methods with yours, e.g., after including js file -
$.fancybox.showActivity = function() {
/* Add your animated gif to page ... */
}
You dont need to change so much just in js file comment some lines:
$.fancybox.showActivity = function() {
//clearInterval(loadingTimer);
loading.show();
//loadingTimer = setInterval(_animate_loading, 66);
};
Thats all and it will work, but remember change in correct file because where are jquery.fancybox-1.3.4.js and jquery.fancybox-1.3.4.pack.js

Javascript - Browser skips back to top of page on image change

I have some simple code to replace an image src. It is working correctly but everytime the image is updated, the browser skips right back to the top of the page.
I have several image tags in my page. All of which hidden, except for the first one. The script just iterates through them and uses the src attribute to update the first image.
Here is the code I am using:
var j = jQuery.noConflict();
var count = 1;
var img;
function update_main_image()
{
count++;
if (j('#main_image_picture_'+count).length > 0)
{
img = j('#main_image_picture_'+count).attr('src');
}
else
{
count = 1;
img = j('#main_image_picture_'+count).attr('src');
}
j(".main_image_picture_auto").fadeOut(1500, function() {
j(this).fadeIn();
j(this).attr("src", img);
});
}
j(document).ready(function()
{
setInterval(update_main_image, 6000);
});
Any ideas what might be causing it?
Any advice appreciated.
Thanks.
Try to add DIV around your IMG.main_image_picture_auto with width and height style properties setted to maximum posible image size, for example:
<div style='width:400px; height:400px; border: 0px; background: transparent; '>
<img class='main_image_picture_auto' src=''/>
</div>
<!-- Where width:400px and height:400px is maximum allowed image size -->
And I think, that is better to use setTimeout instead of setInterval
function update_main_image() {
// ....
setTimeout(update_main_image, 6000);
}
j(document).ready(function() {
setTimeout(update_main_image, 6000);
});
http://jsfiddle.net/UBEWS/

JQuery ready function problems

I am using the dropShadow plugin, and I have a problem with the JQuery ready function.
When I have my code like this:
$(document).ready(function() {
$('div#shadow').dropShadow();
$('#navigation li.mainmenu').bind('mouseover', navigation_open);
$('#navigation li').bind('mouseout', navigation_timer);
});
It will only make the shadow once the drop menu has come out, which is the second function. Any ideas why?
The full code for the JS is:
$(document).ready(
function()
{
$('#navigation li.mainmenu').bind('mouseover', navigation_open);
$('#navigation li').bind('mouseout', navigation_timer);
});
var timeout = 500;
var closetimer = 0;
var ddmenuitem = 0;
var highlightmenu = 0;
var returncolor = 0;
var textreturncolor = 0;
var height = 0;
var originaltop = 0;
var resettop = 0;
var top = 0;
var shadowExists = 0;
var dropshadow = 0;
function drawShadow(){
//draw the shadow only on mouse enter
dropshadow = $(this).find('ul').dropShadow({top: 4, opacity: 1});
$('.dropShadow').css('visibility','visible');
}
function navigation_open()
{ navigation_canceltimer();
navigation_close();
height = $(this).height();
ddmenuitem = $(this).find('ul');
//Double Liners are above 40 pixels
menu = ddmenuitem.find('li');
/*===Need to get the top pos. of the item and adjust it since it is absolute; relative does not work*/
top = ddmenuitem.position().top;
resettop = top;
if (height > 40){
top = top - 53;
}
else{
top = top - 35;
}
ddmenuitem.css('top', top.toString() + "px");
//---ADD A DROP SHADOW...USING JQUERY PLUGIN
ddmenuitem.dropShadow({top: 4, opacity: 1});
$('.dropShadow').css('visibility','visible');
ddmenuitem.css('visibility', 'visible');
returncolor = $(this).find('a#highlight').css('background-color');
textreturncolor = $(this).find('a#highlight').css('color');
highlightmenu = $(this).find('a#highlight').css('background-color','#6487ad');
highlightmenu.css('color','#ffffff');
highlightmenu.css('font-weight','bold');}
function navigation_close()
{ if(ddmenuitem){
ddmenuitem.css('visibility', 'hidden');
ddmenuitem.css('top',resettop);
ddmenuitem.removeShadow();
}
if(highlightmenu){ highlightmenu.css('background-color',returncolor);
highlightmenu.css('color',textreturncolor);
}
}
function navigation_timer()
{
closetimer = window.setTimeout(navigation_close, timeout);}
function navigation_canceltimer()
{ if(closetimer)
{
window.clearTimeout(closetimer);
closetimer = null;}}
document.onclick = navigation_close;
The HTML would be like this for static:
<div id="shadow">
//images here
</div>
I don't know if you need to see anymore, however the drop menu is just a list, but I want to be able to apply this to the static images and it won't until the drop menus come out.
The dropshadow plugin appears to be designed for stationary page elements. From the dropshadow js file:
"This jQuery plug-in adds soft drop shadows behind page elements. It is only intended for adding a few drop shadows to mostly stationary objects, like a page heading, a photo, or content containers"
EDIT: Perhaps you could achieve the effect you're looking for with css? http://robertnyman.com/2010/03/16/drop-shadow-with-css-for-all-web-browsers/
The problem lies within the CSS, when calling dropShadow() for the first time the css for class dropShadow is set to hiddent (this was placed there to make the dynamic pieces work in IE (all other browsers fine without it). In the javascript you can see this by the $('.dropShadow').css('visibility','visible'); being called.

Categories

Resources