I am using javascript for a rotating background image. The problem is, every time the image changes, the page jumps to the top. Hopefully this is an easy fix!
Here is my code:
<script type='text/javascript'>
$(window).load(function(){
var initialBg = $('#slider').css("background-image"); // added
var firstTime = true;
var arr = [initialBg, "url(/wp-content/uploads/2013/03/slider2-explore.png)", "url(/wp- content/uploads/2013/03/slider3-experience.png)"];
(function recurse(counter) {
var bgImage = arr[counter];
if (firstTime == false) {
$("#slider").fadeOut("slow", function(){
$('#slider').css('background-image', bgImage);
});
$("#slider").fadeIn("slow");
} else {
firstTime = false;
}
delete arr[counter];
arr.push(bgImage);
setTimeout(function() {
recurse(counter + 1);
}, 4500);
})(0);
});
</script>
Your page jumps because for an instant #slider is absent and the other page content collapses into its space. Try this:
#slider_wrapper {
height: 550px;
}
<div id="slider_wrapper">
<div id="slider"></div>
</div>
You may also want to preload your background images to prevent odd fadeIn delays.
Related
I have a problem with a javascript. The script causes three elements on my website to be the same size. I would like to load my pictures by lazy load. This makes the rendering incorrect because the size of the elements is calculated by the script without the images. Is it possible to give the javascript a function that it will start only after the images have been loaded successfully by lazy load?
<script type="text/javascript">
jQuery(document).ready(function($){
function kb_equal_height() {
var highest_element = 0;
// Delete the height
$('.navigation-left,.site-content,.widget-area').each(function() {
$(this).removeAttr('style');
});
// Check which element is highest
$('.navigation-left,.site-content,.widget-area').each(function() {
if ($(this).height() > highest_element) {
highest_element = $(this).height();
}
});
// Assign this height to all elements
$('.navigation-left,.site-content,.widget-area').each(function() {
$(this).height(highest_element);
});
};
window.onload = kb_equal_height;
var resizeTimer;
$(window).resize(function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(kb_equal_height, 100);
});
});
</script>
You can use image.onload to call the function when the image finished to load
You might not really see it in action here as the images probably won't take long enough to load for you to see intermediate state but it works
you'll need to clean your cache if you want to see it in action a second time as your browser will load the images from cache the second, third... times
let nbCat = 0
let div = document.getElementById("nbImg")
Array.from(document.getElementsByClassName("doAction")).forEach(img => {
img.onload = imgLoaded // your function here
})
function imgLoaded(e) {
nbCat++
div.textContent = nbCat + " cat" + (nbCat > 1? "s":"") + " loaded"
}
img {
max-height: 50vh
}
<img class="doAction" src="https://r.hswstatic.com/w_907/gif/tesla-cat.jpg">
<img class="doAction" src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg">
<img class="doAction" src="https://pre00.deviantart.net/5d96/th/pre/f/2012/103/d/d/dd0d35acf8ea1817dffe7677f018b5a4-d4vzsbg.jpg">
<img class="doAction" src="https://pre00.deviantart.net/758d/th/pre/f/2018/006/2/7/tigerfieldadjusted_by_mssylviarose-dbz65qt.jpg">
<div id="nbImg">no cat loaded</div>
I am building a image carousel with fade in/out animation with javascript and jquery.
Before the next images fades in, the current image shows up briefly although it's faded out. This happens even though I use onload to make sure the next image is loaded and sized properly.
(The live code is: www.jbkphotographs.com/nepal.html)
function moveToNextImg(){
if(current === imgArray.length-1){
current = 0;
}
else{
current++;
}
updateIndex();
//#imgWrapper is <div> that contains <img>
$("#imgWrapper").fadeOut("slow",loadImg);
}
function loadImg(){
imgName = imgArray[current].getAttribute("src");
nextImg.src = imgName.replace("_Thumb","");
nextImg.id = "currentImg";
nextImg.onload = function(){
if((nextImg.height) > (nextImg.width)){
nextImg.style.width = "42.5%"
}
else{
nextImg.style.width = '750px';
}
imgWrapper.appendChild(nextImg);
}
$("#imgWrapper").fadeIn("slow");
}
I saw it. You have that effects befause you are fading in the image before it has been loaded.
a) You should preload the images , before sliding to have the fadein
fadeout effect
b) Otherwise put the fade in effect in the onload
callback of the images:
function moveToNextImg(){
if(current === imgArray.length-1){
current = 0;
} else {
current++;
}
updateIndex();
//#imgWrapper is <div> that contains <img>
$("#imgWrapper").fadeOut("slow",loadImg);
}
function loadImg(){
imgName = imgArray[current].getAttribute("src");
nextImg.src = imgName.replace("_Thumb","");
nextImg.id = "currentImg";
//This code will run only when images will be loaded
nextImg.onload = function(){
if((nextImg.height) > (nextImg.width)){
nextImg.style.width = "42.5%"
}
else{
nextImg.style.width = '750px';
}
imgWrapper.appendChild(nextImg);
$("#imgWrapper").fadeIn("slow");
}
//any code here will run immediately before the onload runs
}
I wonder if anyone can help or point me in the right direction.
I have a grid of images. What I'm hoping to do is grab all the images on the page and put them in an array(done). Then every 3 seconds I want to to randomly choose an image, fade it out and fade in another image from the same page.
can someone help me with this?
I've got a nice script I made once, it does use jquery though:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<script>
var curIndex = 0;
var src = ['imgs/derp.jpg', 'imgs/derp2.png'];
var fadeTimeInMilliseconds = 2000;
var waitTimeInMilliseconds = 5000;
$(document).ready(function(){
switchImageAndWait(true);
});
function switchImageAndWait(fadeOut2){
if(fadeOut2){
setTimeout(fadeOut, waitTimeInMilliseconds);
}else{
var index = Math.floor((Math.random()*src.length))
if(curIndex == index){
index++;
if(index >= src.length){
index-=2;
}
}
curIndex = index;
$("#swekker").attr("src", src[index]);
fadeIn();
}
}
function fadeOut(){
$("#swekker").fadeTo( fadeTimeInMilliseconds, 0 , function() { switchImageAndWait(false); });
}
function fadeIn(){
$("#swekker").fadeTo( fadeTimeInMilliseconds, 1 , function() { switchImageAndWait(true); });
}
</script>
It's a jquery script script that continuously fades in, waits and fades out again.
To use this script simply add it to an image:
<img width="602" height="400" src="imgs/derp.jpg" id="swekker"/>
I hope someone can help me with this, I have this javascript code that toggles my body background
function changeDivImage() {
imgPath = document.body.style.backgroundImage;
if (imgPath == "url(images/bg.jpg)" || imgPath == "") {
document.body.style.backgroundImage = "url(images/bg_2.jpg)";
} else {
document.body.style.backgroundImage = "url(images/bg.jpg)";
}
}
I activate it with this link:
change
my problem is that it works fine in IE and firefox, but in chrome, the links work twice then stop working, it basically switches to bg_2.jpg then once clicked again switches back to bg.jpg then it never works again :/
also, is there an easier way to accomplish this? css only maybe? basically i have two body background pictures and i want to be able to click on the link to toggle 1, then click again to toggle 2 instead, then back to 1, etc...
lastly, how can i make the two backgrounds fade in and out? instead of just switch between the two?
Use CSS classes!
CSS Rules
body { background-image: url(images/bg.jpg); }
body.on { background-image: url(images/bg_2.jpg); }
JavaScript:
function changeDivImage() {
$("body").toggleClass("on");
}
If you want to fade, you will end up having to fade the entire page. Use can use jQuery's fadeIn and fadeOut.
Here is your solution:
(This also supports additional images).
var m = 0, imgs = ["images/bg.jpg", "images/bg_2.jpg"];
function changeDivImage()
{
document.body.style.backgroundImage = "url(" + imgs[m] + ")";
m = (m + 1) % imgs.length;
}
Here is the working code on jsFiddle.
Here is the jQuery version on jsFiddle.
UPDATE: CROSS-FADING Version
Here is the cross-fading jQuery version on jsFiddle.
You wouldn't want the whole page (with all elements) to fade in/out. Only the bg should fade. So, this version has a div to be used as the background container. Its z-depth is arranged so that it will keep itself the bottom-most element on the page; and switch between its two children to create the cross-fade effect.
HTML:
<div id="bg">
<div id="bg-top"></div>
<div id="bg-bottom"></div>
</div>
<a id="bg-changer" href="#">change</a>
CSS:
div#bg, div#bg-top, div#bg-bottom
{
display: block;
position: fixed;
width: 100%;
/*height: 500px;*/ /* height is set by javascript on every window resize */
overflow: hidden;
}
div#bg
{
z-index: -99;
}
Javascript (jQuery):
var m = 0,
/* Array of background images. You can add more to it. */
imgs = ["images/bg.jpg", "images/bg_2.jpg"];
/* Toggles the background images with cross-fade effect. */
function changeDivImage()
{
setBgHeight();
var imgTop = imgs[m];
m = (m + 1) % imgs.length;
var imgBottom = imgs[m];
$('div#bg')
.children('#bg-top').show()
.css('background-image', 'url(' + imgTop + ')')
.fadeOut('slow')
.end()
.children('#bg-bottom').hide()
.css('background-image', 'url(' + imgBottom + ')')
.fadeIn('slow');
}
/* Sets the background div height to (fit the) window height. */
function setBgHeight()
{
var h = $(window).height();
$('div#bg').height(h).children().height(h);
}
/* DOM ready event handler. */
$(document).ready(function(event)
{
$('a#bg-changer').click(function(event) { changeDivImage(); });
changeDivImage(); //fade in the first image when the DOM is ready.
});
/* Window resize event handler. */
$(window).resize(function(event)
{
setBgHeight(); //set the background height everytime.
});
This could be improved more but it should give you an idea.
There's a cleaner way to do this. As a demo, see:
<button id="toggle" type="button">Toggle Background Color</button>
var togglebg = (function(){
var bgs = ['black','blue','red','green'];
return function(){
document.body.style.backgroundColor = bgs[0];
bgs.push(bgs.shift());
}
})();
document.getElementById('toggle').onclick = togglebg;
http://jsfiddle.net/userdude/KYDKG/
Obviously, you would replace the Color with Image, but all this does is iterate through a list that's local to the togglebg function, always using the first available. This would also need to run window.onload, preferably as a window.addEventListener/window.attachEvent on the button or elements that will trigger it to run.
Or with jQuery (as I notice the tag now):
jQuery(document).ready(function ($) {
var togglebg = (function () {
var bgs = ['black', 'blue', 'red', 'green'];
return function () {
document.body.style.backgroundColor = bgs[0];
bgs.push(bgs.shift());
}
})();
$('#toggle').on('click', togglebg);
});
http://jsfiddle.net/userdude/KYDKG/1/
And here is a DummyImage version using real images:
jQuery(document).ready(function ($) {
var togglebg = (function () {
var bgs = [
'000/ffffff&text=Black and White',
'0000ff/ffffff&text=Blue and White',
'ffff00/000&text=Yellow and Black',
'ff0000/00ff00&text=Red and Green'
],
url = "url('http://dummyimage.com/600x400/{img}')";
return function () {
document.body.style.backgroundImage = url.replace('{img}', bgs[0]);
bgs.push(bgs.shift());
}
})();
$('#toggle').on('click', togglebg);
});
http://jsfiddle.net/userdude/KYDKG/2/
I am using javascript to periodically replace a .png picture, which ist viewed fullscreen as the only content of a site. No matter how I try, in Firefox, after being loaded (as seen via firebug), the new image is always drawn from top to bottom. This takes some seconds. Is there any way to prevent this and show the picture all at once?
This is my current javascript code:
function preloadScreenshotPeriodically(){
var new_screenshot = new Image();
new_screenshot.src = "screenshot.png?defeat_firefox_caching=" + counter;
new_screenshot.id = "screenshot";
counter = counter + 1;
new_screenshot.onload = function(){
loadScreenshot(new_screenshot);
setTimeout("preloadScreenshotPeriodically();", 5000);
};
}
function loadScreenshot(new_screenshot){
document.getElementById("screenshot").parentNode.replaceChild(new_screenshot, document.screenshot);
}
I also tried to use two images, one of them hidden. Then loading the picture in the hidden one and swapping them. Same results :/
In an other version, I fetched the image with Ajax and after loading is complete, changed the url of the img-tag. My hope was, that the browser would recognize the picture had already been loaded and fetch it from the browsercache rather than loading it. But this didn't happen and I ended up with two requests to the server for one picture and the same slow drawing of it as in my other trys.
edit:
Now I tried it like suggested in answer 1. While it works just fine if I switch the picture when I load the next one (I don't want this), trying to switch it as soon as it is loaded (what I want) results in a blank window (very short) and visible loading of the picture as described above.
this works:
<body>
<style type="text/css">
#loaderWin { display:block; height:1px; width:1px; overflow:hidden; }
</style>
<div id="imagewin"></div>
<div id="loaderWin"></div>
<script type="text/javascript">
var screenshotCount=0;
function showFirstImage() {
loadNextImage();
}
function showNewImage() {
loadNextImage();
}
function nextImageLoaded() {
// swapImage();
}
function loadNextImage() {
swapImage();
screenshotCount = screenshotCount +1;
var nextImage = "<img id='loaderWinImg' src='screenshot.png?x="+screenshotCount+"' onload='nextImageLoaded()' />";
document.getElementById('loaderWin').innerHTML = nextImage;
}
function swapImage() {
document.getElementById("loaderWinImg").onload = '';
var newimage=document.getElementById('loaderWin').innerHTML;
document.getElementById('imagewin').innerHTML = newimage;
}
var showImages = setInterval("showNewImage()",15000);
showFirstImage();
</script>
</div>
</body>
</html>
this doesn't work:
<body>
<style type="text/css">
#loaderWin { display:block; height:1px; width:1px; overflow:hidden; }
</style>
<div id="imagewin"></div>
<div id="loaderWin"></div>
<script type="text/javascript">
var screenshotCount=0;
function showFirstImage() {
loadNextImage();
}
function showNewImage() {
loadNextImage();
}
function nextImageLoaded() {
swapImage();
}
function loadNextImage() {
screenshotCount = screenshotCount +1;
var nextImage = "<img id='loaderWinImg' src='screenshot.png?x="+screenshotCount+"' onload='nextImageLoaded()' />";
document.getElementById('loaderWin').innerHTML = nextImage;
}
function swapImage() {
// loadNextImage();
document.getElementById("loaderWinImg").onload = '';
var newimage=document.getElementById('loaderWin').innerHTML;
document.getElementById('imagewin').innerHTML = newimage;
}
var showImages = setInterval("showNewImage()",15000);
showFirstImage();
</script>
</div>
</body>
</html>
The problem can be seen here (in firefox problem like described above, in chrome there are no pauses between pictureloads and there is a blank window in between picture changes): http://sabine-schneider.silbe.org:1666/test.html
And here, what Rob suggested in answer 1 without any changes (displays the picture fine in firefox, but not in chrome - there I get a blank window in between picture changes): http://sabine-schneider.silbe.org:1666/test0.html
sounds like the image is "progressive" ( interlaced) and the preload needs more time for it to complete download.
You can set a width and height to the image also for a more stable presentation
( poss )
using
?defeat_firefox_caching=" + counter;
means you never cache the image ( which has confused me about your question ) - remove that line( unless you need it for something you haven't mentioned)
update: Can you try ...
<style type="text/css">
#loaderWin { display:block; height:1px; width:1px; overflow:hidden; }
</style>
<div id="imagewin"></div>
<div id="loaderWin"></div>
<script type="text/javascript">
var screenshotCount=0;
function showNewImage() {
screenshotCount = screenshotCount +1;
var newimage=document.getElementById('loaderWin').innerHTML;
document.getElementById('imagewin').innerHTML = newimage;
var nextImage = "<img src='screenshot.png?defeat_firefox_caching="+screenshotCoun+"'/>";
document.getElementById('loaderWin').innerHTML = nextImage;
}
var showImages = setInterval("showNewImage()",5000);
</script>