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

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/

Related

How to darken an image

I want to darken an image, but it isn't fully black in the end, because I can see the image some extent. I want to use vanilla JS only (no jQuery).
var element = document.getElementById("img");
var colorArr = ["#fff","#ddd","#bbb","#999","#777","#555","#333","#000",];
var counter = 0;
var j=0;
var i = setInterval(function(){
if(j < colorArr.length){
element.style.backgroundColor = colorArr[j];
j++;
}
counter++;
if(counter === 8) {
clearInterval(i);
}
}, 250);
div.darken img {
background-color: white;
}
<html>
 <body>
 
<div class="darken">
<img id="img"
src="http://davidrhysthomas.co.uk/linked/astrid_avatar2.png" />
</div>
</body>
</html>
Try adding a second element above your <img> tag position it absolutely with a width and height that is the same as the image, and target that in your element variable in your code.
var element = document.getElementById("overlay");
var colorArr = ["#fff","#ddd","#bbb","#999","#777","#555","#333","#000",];
var counter = 0;
var j=0;
var i = setInterval(function(){
if(j < colorArr.length){
element.style.backgroundColor = colorArr[j];
j++;
}
counter++;
if(counter === 8) {
clearInterval(i);
}
}, 250);
#overlay {
position: absolute;
width: 400px;
height: 400px;
}
<div id="overlay"></div>
<img id="img" src="http://davidrhysthomas.co.uk/linked/astrid_avatar2.png" />
Draw another rect with high transparency to cover image and slowly increase its opacity
Despite you asked 4 years ago but after testing your sample code, and I couldn't see the image in the end, here is a small fix to your original code that guarantees the image cannot be seen when the loop ends:
function darkenImage() {
var element = document.getElementById("img");
if (element.stop) return;
var colorArr = ["#eee","#ccc","#aaa","#888","#666","#444","#222"];
element.counter=0;
var i = setInterval(function() {
if (element.counter<colorArr.length) {
element.style.backgroundColor = colorArr[element.counter];
element.counter++;
} else {
clearInterval(i);
element.width=element.offsetWidth;
element.height=element.offsetHeight;
element.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==";
element.stop=true;
}
}, 250);
}
div.darken img {
background-color: white;
}
<div class="darken">
<img id="img" src="http://davidrhysthomas.co.uk/linked/astrid_avatar2.png" onload="darkenImage();"/>
</div>
I changed the color array so it doesn't feel at the end that the bgcolor jump is too big. Also I removed the initial value #fff and the last value #000 because they are not needed. Another change was that there were unnecesary variables and I put the counter as a property of the image element.
Finally instead of setting the background color to #000 I replaced the image with a single black dot base64 image.
If you can see your image in the end, I can only assume it is something in your screen or in your eyes that keeps cache/memory of the original image, because it was replaced completely.
Some final observations:
The css with white background and the div around the image are unnecesary in the example but I kept them because you might have another use for it.
For this to work properly the image must have only two colors, black for viewable pixels and transparent color for background. Additional changes must be done for an opaque image using opacity.

How to create automatic image gallery slideshow by using HTML,CSS and JavaScript

This isn't working, can anyone help?
I am trying to build a website where the images slide to the right. I have tried the solution from a previous post but that still didnt work.
(function () {
var imgLen = document.getElementById('imgGallary');
var images = imgLen.getElementsByTagName('img');
var counter = 1;
if (counter <= images.length) {
setInterval(function () {
images[0].src = images[counter].src;
console.log(images[counter].src);
counter++;
if (counter === images.length) {
counter = 1;
}
}, 4000);
}
})();
.container{
position:relative;
width:600px;
height:330px;
border-radius:5px;
border:4px solid black;
overflow:hidden;
margin-left:320px;
}
#imgGallary > img
{
width:700px;
height:330px;
}
<div id="imgGallary" class="container">
<img src="image/lake-louise-51543_960_720.jpg" />
<img src="image/snow-in-pine-tree-1265118__340.jpg" />
<img src="image/winter-385640_960_720.jpg"/>
</div>
This should fix the issue you're having with the first image not coming in correctly. Keep the HTML and CSS the same. Change the JavaScript. Here I use window.onload, but I think your self invoking method would work, too. As for sliding it to the right, the way you have things set up is very prohibitive. I tried creating a clone and sliding the clone, but there are conflicts that make it not worth while.
If you want to slide the image, I would actually go a different route. Rather than changing the src attribute, why don't you just stack the images on top of each other using absolute positioning and z-indexes? Then you can get rid of that overflow property and just apply the border to the image, or better yet set those images as div background images (ie. background: url('lake.jpg') center center no-repeat), that way you don't even have to worry about sizing them, and they won't get distorted. In CSS, give each div a transition of "transform 0.25s" (or something to that effect). Then you can just apply a transform to them in javascript to slide them to the right. To bring them back, simply get rid of the transition value and assign a transform value of 0 to the image, but make sure the z-index is lower than the currently displayed image. If you do go the transform route, remember to add your -ms- and -webkit- prefixes to be accessible to older browsers: http://caniuse.com/#search=transform
Anyway, that's just one thought. Here's the code to fix your issue with loading the wrong image. By the way, I would consider using jQuery next time for complicated css rulings (if you decide to go my route). Good luck!
JS
window.onload = function () {
var imgLen = document.getElementById('imgGallary');
var images = imgLen.getElementsByTagName('img');
var counter = 1;
//Store the src attributes in an array
var src = [];
for (var i = 0; i < images.length; i++) {
src[i] = images[i].src;
}
console.log(src);
setInterval(function () {
if (counter < images.length) {
images[0].src = src[counter];
console.log(src[counter]);
counter++;
}
// Here we're saying if the counter is equal to the length of images, go back to the first images
// and reset the counter.
else {
images[0].src = src[0];
console.log(src[0]);
counter = 1;
}
}, 4000);
}
Once you assign a new src value to the first image tag, you can't get back the original src value of that tag.
You need to make an empty img tag withour src attribute, so that you can assign the src value to that tag.
(function () {
var imgLen = document.getElementById('imgGallary');
var images = imgLen.getElementsByTagName('img');
var counter = 1;
if (counter <= images.length) {
setInterval(function () {
images[0].src = images[counter].src;
console.log(images[counter].src);
counter++;
if (counter === images.length) {
counter = 1;
}
}, 1000);
}
})();
.container{
position:relative;
width:600px;
height:330px;
border-radius:5px;
border:4px solid black;
overflow:hidden;
margin-left:320px;
}
#imgGallary > img
{
width:700px;
height:330px;
}
<div id="imgGallary" class="container">
<img />
<img src="http://placehold.it/350?text=img1" />
<img src="http://placehold.it/350?text=img2" />
<img src="http://placehold.it/350?text=img3"/>
</div>

Fade In / Fade Out background images without white background

I want to create a website with background images that change over time with a fade in/fade out effect, but I don't want to use the existing jQuery fade in/fade out effect because with when one image faded out, a white background appeared before other image faded in. I found a plugin named Maximage that suits my request but it uses img tags while I want to work with background-image CSS (I have a good reason for doing this). Does anyone know how to do this?
Here's my HTML code:
<div id="wrapper">
//My contain here
</div>
Here's my JavaScript code so far:
//Auto change Background Image over time
$(window).load(function() {
var images = ['img/top/bg-1.jpg','img/top/bg-2.jpg','img/top/bg-3.jpg'];
var i = 0;
function changeBackground() {
$('#wrapper').fadeOut(500, function(){
$('#wrapper').css('background-image', function () {
if (i >= images.length) {
i = 0;
}
return 'url(' + images[i++] + ')';
});
$('#wrapper').fadeIn(500);
})
}
changeBackground();
setInterval(changeBackground, 3000);
});
Example: http://www.aaronvanderzwan.com/maximage/examples/basic.html
AHH ! Finally ! I found a nice technique ! I'm using a double wrapper.
The problem in your code is a bit logical. You can't fadeOut and fadeIn at the same time a single wrapper.
So the idea is to create two wrapper and to switch between them back and forth. We have one wrapper called: "wrapper_top" that encapsulate the second wrapper called: "wrapper_bottom". And the magic was to put beside the second wrapper: your content.
Thus having the structure ready which is the following:
<div id='wrapper_top'>
<div id='content'>YOUR CONTENT</div>
<div id='wrapper_bottom'></div>
</div>
Then a bit of JS+CSS and voilà ! It will be dynamic with any amount of images !!!
Here is the implementation: http://jsbin.com/wisofeqetu/1/
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function() {
var i =0;
var images = ['image2.png','image3.png','image1.png'];
var image = $('#slideit');
//Initial Background image setup
image.css('background-image', 'url(image1.png)');
//Change image at regular intervals
setInterval(function(){
image.fadeOut(1000, function () {
image.css('background-image', 'url(' + images [i++] +')');
image.fadeIn(1000);
});
if(i == images.length)
i = 0;
}, 5000);
});
</script>
</head>
<body>
<div id="slideit" style="width:700px;height:391px;">
</div>
</body>
</html>
If it doesn't have to be background-image, you can place all the images in your #wrapper, in <img>, it will work like a charm:
<div id="wrapper">
<img src="firstImage" class="imageClass"></img>
<img src="secoundImage" class="imageClass"></img>
<img src="thirdImage" class="imageClass"></img>
</div>
then some style. Every image has to be in same spot, so add position relative to #wrapper, and position absolute to .imageClass:
#wrapper{
position: relative;
}
.imageClass{
position: absolute;
top: 0;
left: 0;
display: none;
}
display: none; will hide every image.
Now some JQuery. To appear first image when window load write this:
$(window).load(function() {
$('.imageClass').eq(0).show();
});
by the .eq() "command" you can specify which one element with class '.imageClass' you want to use exactly. Starts with 0. After that just do something like that:
function changeBackground() {
var current = 0;
//tells which image is currently shown
if(current<$('.imageClass').length){
//loop that will show first image again after it will show the last one
$('.imageClass').eq(current).fadeOut(500);
current++;
$('.imageClass').eq(current).fadeIn(500);
} else {
$('.imageClass').eq(current).fadeOut(500);
current=0;
$('.imageClass').eq(current).fadeIn(500);
}
}
changeBackground();
setInterval(changeBackground, 3000);
});
That should work, hope you will like it.
You may also use jQuery plugin backstretch.

Wait for image full load on ajax action

On my page there is ajax action, which loads div, that contain image on left and text on right.
The problem: first of all text loads, and on the left (it aligned left), then image loads, text shifts on right, and that looks really not smooth.
I tried something like :
$('div#to_load').ready(function() {
$('div#to_load').fadeIn();
});
but that doesn't help.
What can I do?
Update
I think you have to try this trick found here :
$("<img />", { src:"thelinkofyourimage"}).appendTo("div#to_load").fadeOut(0).fadeIn(1000);
Have a look to this fiddle : http://jsfiddle.net/qYHCn/.
You could track when all the images have loaded like so
var element = $('div#to_load');
var images = element.find('img');
var count = images.length;
for( var i = 0; i < count; i++) {
$(images[i]).load(function(){
count--;
if( count === 0 ){
element.fadeIn();
}
});
}
You could smoothly animate it in with jQuery (handy anyway when you are doing your ajax requests with jQuery):
jQuery
$("body").prepend('<img src="http://placehold.it/150x150" alt="img">');
$("img").animate({
opacity: 1,
left: 0
}, 700);
CSS
img {
float: left;
margin-right: 0.8em ;
left: -300px;
position: relative;
}
Fiddle.
Try to load image and text separately, not at once.
And for the shifting problem put image inside another div and define the size when it loads. Then text can't come to image space since we already giving space for image div.
sample code
$('#ImageID')
.load(
function(){
//Do stuff once the image specified above is loaded
$('#textId').html('your text');
}
);
If you don't want content to shift, you must declare the size the image will take up so that the required space is already accounted for when the browser does it's render.
Make sure you declare the size of the image, or the size of the container before you load
<div id="to_load">
<img src="...." height="400" width="400" />
</div>
or
<div id="to_load" style="height:400px;width:400px;overflow:hidden">
..dynamic content
</div>
Declaring image size either on the img element or in your stylesheet is a best practice recommendation anyways
Reflows & Repaint
Maybe you'd like something like this
#to_load {
width: 523px;
height: 192px;
}
#to_load img {
display: none;
}
setTimeout(function() {
$("<img />", { src:"http://ejohn.org/apps/workshop/adv-talk/jquery_logo.png"})
.on('load', function(){
$(this).appendTo("#to_load").fadeIn(500);
});
},1000);
http://jsfiddle.net/AWntU/

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');
}
});
});

Categories

Resources