I am looking to create a photographic website which has a background image that changes every few seconds. I have the images changing by using:
<script type='text/javascript'>
var imageID=0;
function changeimage(every_seconds){
//change the image
if(!imageID){
document.getElementById("myimage").src="John%20Gallacher%20Photography/images/composite/Composite%201.jpg";
imageID++;
}
else{if(imageID==1){
document.getElementById("myimage").src="John%20Gallacher%20Photography/images/composite/Composite%202.jpg";
imageID++;
}
else{if(imageID==2){
document.getElementById("myimage").src="John%20Gallacher%20Photography/images/composite/Composite%203.jpg";
imageID=0;
}
}
}
//call same function again for x of seconds
setTimeout("changeimage("+every_seconds+")",((every_seconds)*5000));
}
</script>
</head>
<body onload='changeimage(2)'>
<div>
<img id="myimage" src="John%20Gallacher%20Photography/images/composite/Composite%201.jpg"/>
</div>
Is it possible to make the images fade in and then out again, and if so what would be the easiest way to do this. I have a basic understanding of html and css, my javascript is very basic. Any help would be great thanks
What is the support list? If you're not worried about older IE, then you can go with CSS Transitions for the transition and change the state with js
http://jsfiddle.net/Bushwazi/MYKFT/
#myimage {
-webkit-transition:all 1s linear 0s;
-moz-transition:all 1s linear 0s;
-o-transition:all 1s linear 0s;
transition:all 1s linear 0s;
-webkit-transform: translate3d(0,0,0); /* Fixes trails in Chrome */
}
And then just use js to change the opacity, then image, the opacity...
var imageID = 0,
ti = document.getElementById("myimage");;
var changeImage = function(t){
// change the opacity of the image to 0, let the css control the animation
ti.style.opacity = "0.0";
ti.style.filter = 'alpha(opacity=00)'; // IE fallback
// after 1 second (the animation), change the image
setTimeout(function(){
//change the image
switch(imageID){
case 0:
ti.src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcTM7c8EFwQ_PseqOEblAtm9qXali9kzvBKsmrGDECLYu1HJP3EO";
break;
case 1:
ti.src="https://si0.twimg.com/profile_images/2317326635/3kglmsqti3msjlb1nr60.png";
break;
case 2:
// return to the original image
ti.src="http://upload.wikimedia.org/wikipedia/en/c/cc/FPO_mark3.jpg";
break;
default:
// do nothing
}
if(imageID == 2){
imageID = 0;
} else {
imageID++;
}
// change the opacity of the image to 0, let the css control the animation
ti.style.opacity = "1.0";
ti.style.filter = 'alpha(opacity=100)'; // IE fallback
},1000);
} // close changeimage
//call same function again for x of seconds
window.setInterval(changeImage, 5000);
You may use jQuery. This has a number of transitions including fadeIn() and fadeOut().
Apply those functions to your images like this:
$("#image_id").fadeIn(); $("#image_id").fadeOut();
But firstly in your head you need to include jQuery. You can do that like this:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
The #image_id is the id= of the <img> in your HTML Markup.
You can use a simple plugin for that, like jQuery Cycle. The code should look like this:
<head>
...
<script src="js/jquery-1.10.1.min.js"></script>
<script src="js/jquery.cycle.lite.js"></script>
...
</head>
...
<div class="fader">
<img src="image1.jpg" width="100px" height="100px">
<img src="image2.jpg" width="100px" height="100px">
<img src="image3.jpg" width="100px" height="100px">
</div>
...
<script>
$('.fader').cycle();
</script>
</body>
Where you shoud replace '/js' with the path to that files (that you should download).
I think a plugin is a lot of overhead for something that you can do with a little code.
I set up a quick example for you:
http://jsfiddle.net/Pevara/XcBTx/1/
A few remarks:
- I chose to work with background images, as I believe a background is what you are after, and you would not want the picture to show up on print. You could argue that for a photography website the background image is actual content, but changing the code to work with images in stead should be easy.
- Note that I use 2 div's for the images, so I can fade one in and one out. Perhaps it would be better to add the second one with javascript to avoid unnessacary markup. The first div I would keep, cause you want users without javascript to see at least one photo. You could consider setting it on the body, but again, I leave that up to you.
- It will be probably nessacary to preload the images, and wait for them to be loaded before you start the slideshow. Should not be to hard, plenty of information out there.
And the javascript (to be put in the $(window).load handler):
// the list of background images
var myImages = ['http://placekitten.com/900/400','http://placekitten.com/550/600'];
// the transition speed
var fadeSpeed = 500;
// the time between transitions
var playSpeed = 2000;
function fadeToNextImage() {
// -- prepare some vars
// the image wrappers
var $bg1 = $('#bg1');
var $bg2 = $('#bg2');
// the index of the next image in our array
var nextNr = parseInt($bg1.data('number')) + 1;
// if the index is larger then the number of images,
// we want the first image
if (nextNr > myImages.length - 1) { nextNr = 0; }
// the path to the next image
var nextImg = 'url(' + myImages[nextNr] + ')';
// set the image as background on bg2
$bg2.css('background-image', nextImg);
// fade out bg1
$bg1.fadeOut(fadeSpeed);
// fade in bg2
$bg2.fadeIn(fadeSpeed, function() {
// when the cross fade is ready
// set the image as background on bg1
$bg1.css('background-image', nextImg);
// update the number attribute
$bg1.data('number', nextNr);
// show bg1 (which now contains the same image as bg2)
$bg1.show();
// hide bg2 (to prepare it for the next slide)
$bg2.hide();
});
}
// start the slideshow
var interval = window.setInterval(function() {fadeToNextImage();}, playSpeed + fadeSpeed);
I put plenty of comments in there, but feel free to ask!
Related
I have a background image set to loop infinitely on a 10 second CSS animation. I'm using jQuery to find the height of the image based on the users screen size. Then I use background-position-y and go from 0 to exactly the height of the image. This creates a smooth loop, for any desktop screen size (A separate bg image will be used for mobile).
Issue: On page load, the animation appears to not work correctly on the first iteration of the loop. The image pans slowly for 10s, "jumps" back to the original position, then works correctly for all future iterations of the loop.
Looking for help on how to make the first animation loop, the first 10s to work how it should/like the remaining loops and the path appears to be infinite.
JS Fiddle: https://jsfiddle.net/bennimbl/7xkyhgz2/3/
View the fiddle, note it's slowness for 10 seconds, then note it works correctly after then.
The problem is the starting set up of the background image.
There is a bit of a mixture in this code. It seems as though an attempt was made to use CSS keyframes for the animation and that this was then abandoned and JS/jquery used instead on a timeout.
This snippet simplifies things by getting rid of JS/jquery animation and going back to the keyframes (this can in any case help CPU usage).
The code already sets a CSS variable --height to the height of the current viewport so this is used in the keyframes to move the background image from a top position of 0 to a top position of -this height.
There was a spurious : after animation in the CSS set up which has been removed.
The only other change that has been made is to set the background image to top 0 from the start rather than at the bottom of the viewport.
var fullhdWidth = 1920;
var fullhdHeight = 2685;
var fullhdRatio = fullhdWidth / fullhdHeight;
$('#s1Bg').ready(function() {
var containerWidth = $(this).width();
var containerHeight = $(this).height();
var containerRatio = containerWidth / containerHeight;
var realWidth = null;
var realHeight = null;
if (containerRatio > fullhdRatio) {
realWidth = containerWidth;
realHeight = containerWidth / fullhdRatio;
//alert(realWidth + ' ' + realHeight);
} else {
realWidth = containerHeight * fullhdRatio;
realHeight = containerHeight;
//alert(realWidth + ' ' + realHeight);
}
$('<style>').text(`:root{--height: ${realHeight};}`).appendTo(document.head);
$("#s1Bg").css({
'width': '100vw',
'height': '100vh',
'margin': '0',
'background': '#000000 url("https://iili.io/sVrZXe.jpg") 0% 0%/cover repeat-y',
'animation': 'rideup 10s linear infinite'
});
});
body {
margin: 0;
}
#keyframes rideup {
from {
background-position-y: 0;
}
to {
background-position-y: calc(-1px * var(--height));
}
}
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
</head>
<div id="s1Bg" class="s1-bg"></div>
I've made a little change on your css and gotime function to start at the realHeight and then animate to background-position-y: 0. I moved some css to the css file to since it didn't belong in the js file. Though i couldn't really figure out why it didn't worked out in the previous fiddle it does in this one
JS:
$("#s1Bg").css({
'background-position-y': realHeight,
'animation:' : 'rideup 10s linear infinite'
});
var gotime = function() {
$('#s1Bg').animate({
'background-position-y': 0,
}, 10000, 'linear', function() {
$(this).css('background-position-y', realHeight);
gotime();
});
}
CSS:
#s1Bg {
height: 100vh;
width: 100vw;
margin: 0;
background-image: url('https://iili.io/sVrZXe.jpg');
background-size: cover;
}
I want to seamlessly expand my div (in a non-jarring way) when the text inside it changes:
The CSS transition: all 2s ease; is working great for colour changes, manually setting width, etc (as you can try out in the jsfiddle - click button to toggle width). but when the inner text of the div is changed the div just jumps to the new width without any transition.
How can I get the transition working when the inner text changes?
Thanks!
Because the default width of the div will be auto (100%), it can't transition from auto to a numerical value.
I don't think dynamically changing a width of an element depending on its content is possible, as there is no transition for content. The content of an element changes instantly and the width does not get a numerical value in your case - but adjusts.
A solution that can be sometimes applicable: Using a function to roughly calculate your text's width so that you'll be able to set a numerical width for your element on change.
Here's a simple one that I made.
function getTextWidth(text, css) {
var e = $('<span></span>'); // dummy element
e.css(css); // set properties
e.text(text); // set test
var width = e.appendTo($('body')).width(); // append and get width
e.remove(); // remove from DOM
return width;
}
Put together an example of usage.
Hi abagshaw try this script to solved your problem.
var big = false;
$('#content').on('click', function(e) {
if(!big)
{
$( this).animate({
width: "600px" }, 500 );
this.innerHTML = "MORETEXTMORETEXTMORETEXTMORETEXTMORETEXTMORETEXTMORETEXT";
big = true;
}
else
{
$( this).animate({
width: "200px" }, 500 );
this.innerHTML = "LESSTEXTLESSTEXT";
big = false;
}
});
.ui.transitioning.button{
transition:all 0.5s ease-in-out;-webkit-transition:all 0.5s ease-in-out;
width:200px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.0.7/semantic.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ui transitioning teal button" id="content">LESSTEXTLESSTEXT</div>
I've search ALL day and couldn't find anything. I'm trying to fade an image to be transparent with another image. Meaning - when I click a button the transition starts but you have to keep clicking the button to see the 2nd image. Example: 2 of the same images but one is night image and one is a day image. I want to transition day to night, not by fading the opacity to 0 and then 1, but to have it clicked continuously and you see the transition.
I think here is what you have searched for
$(document).ready(function(){
var opacityOfNight = 0;
$('.turnNightBtn').click(function(){
if (opacityOfNight == 1){
opacityOfNight = 0;
} else {
opacityOfNight += 0.05;
if(opacityOfNight > 1) {
opacityOfNight = 1;
}
}
$('.night_img').css({
opacity : opacityOfNight
});
});
});
http://jsfiddle.net/nUBmh/
I put together a basic example that you can use as a basis to get to your goal. I've layered one image over top of the other and then set up a jQuery function to lower the opacity of the top image by 25% per click. You can adjust the class names and values to match your HTML and desired fade amount per click. Hopefully this helps.
$(function(){
var imageOpacity = 1;
$('button').click(function(){
if(imageOpacity > 0){
imageOpacity = imageOpacity - .25;
$('.image2').css('opacity', imageOpacity);
}
});
});
JSFiddle Example - http://jsfiddle.net/tM9P7/
If I have an image tag like the following:
<img src="myimage.jpg" />
and if I add "async" to it:
<img async src="myimage.jpg" />
will the image load asynchronous?
The way to async load (lazy load) the content is to not set the 'src' attribute and then execute a script that loads the images once DOM-ready is launched.
<img data-lazysrc='http://www.amazingjokes.com/images/20140902-amazingjokes-title.png'/>
and with jQuery (or possible with plain JavaScript too) use below code (as suggested here):
<script>
function ReLoadImages(){
$('img[data-lazysrc]').each( function(){
//* set the img src from data-src
$( this ).attr( 'src', $( this ).attr( 'data-lazysrc' ) );
}
);
}
document.addEventListener('readystatechange', event => {
if (event.target.readyState === "interactive") { //or at "complete" if you want it to execute in the most last state of window.
ReLoadImages();
}
});
</script>
var img = new Image(),
url = "myimg.jpg",
container = document.getElementById("holder-div");
img.onload = function () { container.appendChild(img); };
img.src = url;
This would start loading an image as soon as you request it in-script, and whenever the image was done loading, it would grab and add the image to it.
There are lots of other ways of doing this...
This is just a dead-simple example of async loading of a single image.
But the moral is this:
For async loading to work, either load it in JavaScript and use the onload, or include the image tag on the page, without the src attribute (specify the width and height in HTML), and go back at some point, in JS, and set the image URL.
The modern way to do this is with the loading attribute for images and iframes.
Attribute: loading=lazy
This will defer loading of the content until the element reaches a calculated distance from the viewport (that just means, it's got quite likely that the user will scroll it into view).
<img src="defer.png" loading="lazy" alt="An Awesome Image" width="500" height="400">
Setting the attribute to lazy invokes the new behaviour.
This is already in Chromium since v76, but might not hit non-Chromium browsers until it goes through the usual specification shennanigans.
If you are going to defer loading using a script, it would be worth writing the image with the lazy attribute and polyfilling the behavior as opposed to working off of a class name, etc. That way, you can allow the native version to take over as it becomes available.
Forced Eager Loading
Automatic lazy loading may become a feature of lightweight browsing, in which case, you may want to do the inverse and force an image to load. You can use the same loading attribute with a value of eager to ask the browser to grab the image even if it might otherwise choose not to.
<img src="defer.png" loading="eager" alt="An Awesome Image" width="500" height="400">
Further reading
View the pull request for the WHATWG spec
Fallback JavaScript with notes about perhaps not using fallbacks
An alternate way to async load an image is by using Promise in javascript, which serves the purpose of doing things asynchronously.
function asyncImageLoader(url){
return new Promise( (resolve, reject) => {
var image = new Image()
image.src = url
image.onload = () => resolve(image)
image.onerror = () => reject(new Error('could not load image'))
})
}
// then use it like this
var image = asyncImageLoader(url)
image.then( res => {
console.log(res)
})
<img async src="myimage.jpg" />
The image tag doesnt supports any async attribute.
http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element
While several other answers highlight ways to fetch images asynchronously, it may also be helpful to know that the <img /> tag supports an attribute that serves as a hint to the browser that may result in images being be decoded asynchronously. It doesn't appear to be supported by Internet Explorer.
<img src="myimage.jpg" decoding="async"/>
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#attr-decoding
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding
https://github.com/whatwg/html/issues/1920
If you're using jQuery, I did something simple, yet effective, like this:
HTML
<div data-lazy-load-image="/Images/image-name.png" data-image-classname="pop-in"></div>
JavaScript
$(function () {
$("[data-lazy-load-image]").each(function (index, element) {
var img = new Image();
img.src = $(element).data("lazy-load-image");
if (typeof $(element).data("image-classname" !== "undefined"))
img.className = $(element).data("image-classname");
$(element).append(img);
});
});
CSS
#-webkit-keyframes pop-in {
0% { opacity: 0; -webkit-transform: scale(0.5); }
100% { opacity: 1; -webkit-transform: scale(1); }
}
#-moz-keyframes pop-in {
0% { opacity: 0; -moz-transform: scale(0.5); }
100% { opacity: 1; -moz-transform: scale(1); }
}
#keyframes pop-in {
0% { opacity: 0; transform: scale(0.5); }
100% { opacity: 1; transform: scale(1); }
}
You could extend this to include additional optional attributes for each image, but you get the idea.
This will wait until the DOM is ready, then dynamically (async) load the images into the element that you mark with the data-lazy-load-image attribute. I included the CSS to make the images "pop in" when they are loaded.
While #Norguard's example is quite simple and easy enought for an image or two, I have found echo.js pretty handy for lazy-loading, https://github.com/toddmotto/echo.
It does lazy-loading images with data-* attributes and comes with some neat other things too.
<img data-echo="img/photo.jpg">
<script src="dist/echo.js"></script>
<script>
echo.init();
</script>
I have used the following approach with jQuery.
First, don't use a "src" attribute in the image tag, but put your source into a different attribute, like this:
<img async-src="/mydirectory/myimage.jpg" />
Then, within the jQuery document-ready function, I use this code to copy the element's async-src to the element's actual src:
$("img[async-src]").each(function(index) {
$(this).attr("src", $(this).attr("async-src"));
});
Notes:
jQuery's .each function may process the tags in the sequence they are coded in the HTML/DOM, but image sizes and network issues may mean that images don't actually load sequentially. In other words, your third async-src image might visually appear onscreen before the first has finished loading.
If your page layout relies on the pixel dimensions of that image file — e.g. you're not defining the image's dimensions via tag attributes, CSS, or a parent element — then you may have to use a "src" attribute on the original file pointing to a blank white or clear GIF of the dimensions you want.
Finally, if you want to process some code after the async loading of the image — for example, to handle a fading effect or change a CSS tag relevant to the element — expand the jQuery like this:
$("img[async-src]").each(function(index) {
$(this).load(function() {
// code to run after loading
});
$(this).attr("src", $(this).attr("async-src"));
});
It might be too late of an answer but recently was facing the same issue and the "lighthouse" in the console suggested that I should follow what's mentioned here in the link:
enter link description here
Basically, I did the following as suggested and it works really well:
<script src="lazysizes.min.js" async></script>
<!-- Images End -->
</body>
You may download the lazysizes.min.js from https://raw.githubusercontent.com/aFarkas/lazysizes/gh-pages/lazysizes.min.js
and source it locally.
Then, add the class lazyload to images that should be lazy loaded. In addition, change the src attribute to data-src.
For example:
<img data-src="images/flower3.png" class="lazyload" alt="">
You may be wondering why it is necessary to change the src attribute to data-src. If this attribute is not changed, all the images will load immediately instead of being lazy-loaded. data-src is not an attribute that the browser recognizes, so when it encounters an image tag with this attribute, it doesn't load the image. In this case, that is a good thing, because it then allows the lazysizes script to decide when the image should be loaded, rather than the browser.
Visit the reference for better understanding.
Hopefully it'll be of help to someone :)
You can read more about lazyload attribute:
<img src="myimage.jpg" alt="some description" lazyload/> - with default values
or you can prioritize:
<img src="myimage.jpg" alt="some description" lazyload="1"/>
<img src="myimage.jpg" alt="some description" lazyload="2"/>
I am trying to create two buttons, one that will expand a div and one that will collapse it. I've tried to modify this code, but I cant seem to get it to work. I think I just dont understand how to not toggle a link.
I am also trying to make the DIV appear when the page loads. I'm not even sure if this is possible with the way I am writing the code.
Can anyone help me understand what I need to do to get this to work.
http://jsfiddle.net/XUjAH/93/
I am trying to avoid using .slideUp/.slideDown it seems to be interfering with another plugin I am using on the page.
$('#click-meopen').click(function() {
var height = $("#this").height();
if( height > 0 ) {
$('#this').css('height','0');
} else {
$("#this").css({'position':'absolute','visibility':'hidden','height':'auto'});
var newHeight = $("#this").height();
$("#this").css({'position':'static','visibility':'visible','height':'0'});
$('#this').css('height',newHeight + 'px');
}
});
$('#click-meclose').click(function() {
var height = $("#this").height();
if( height > 0 ) {
$('#this').css('height','0');
} else {
$("#this").css({'position':'absolute','visibility':'hidden','height':'auto'});
var newHeight = $("#this").height();
$("#this").css({'position':'static','visibility':'visible','height':'0'});
$('#this').css('height',newHeight + 'px');
}
});
All following text is just IMHO :)
See my exmple here - http://jsfiddle.net/XUjAH/99/
html:
<p id="click-meopen">click me to open</p>
<p id="click-meclose">click me to close</p>
<div id="this">
<div id="content">here<br />is<br />a<br />bunch<br />of<br />content<br />sdf</div>
</div>
as for JS:
$('#click-meopen').click(function() {
$("#this").height($("#content").height());
});
$('#click-meopen').click();
$('#click-meclose').click(function() {
$("#this").height('0');
});
as for CSS it should be the same you have.
UPD: Seems that animation is a bit flaky - when you set 'height: auto' - div is visible from the beginning, however close button ignores animation on first click(I have Chrome with latest update) so I've added some workaround. Also added other styles to support this animation for other browsers like Firefox and Opera and not only for those who support -webkit.
http://jsfiddle.net/XUjAH/110/
in CSS added class and removed 'transition' from the main style:
.with-animation {
-webkit-transition: height 1s ease-in-out;
-moz-transition: height 1s ease-in-out;
-o-transition: height 1s ease-in-out;
transition: height 1s ease-in-out;
}
In JS:
// However our div already have proper size this line
// prevents instantaneous close on first click, don't know why
$("#container").height($("#content").height());
$('#click-meopen').click(function() {
$("#container").height($("#content").height());
});
$('#click-meclose').click(function() {
// If we add class with-animation on upper level div will
// start animation on page load
$("#container").height('0').addClass("with-animation");
});
If you can use toggle then all you need is $("#this").toggle('slow');, but you must replace height: 0; with display: none;
$('#click-meopen').click(function() {
$('#this').show();
});
$('#click-meclose').click(function() {
$('#this').hide();
});
http://jsfiddle.net/XUjAH/95/
Or with toggle
$('#click-meopen').click(function() {
$('#this').toggle();
});
http://jsfiddle.net/XUjAH/96/
You are trying to change this to buttons ?
<input type="submit" id="click-meopen" value="open"></input>
<input type="submit" id="click-meclose" value="close"></input>
<div id="this">here<br />is<br />a<br />bunch<br />of<br />content<br />sdf</div>
That's not hard to do.
I would also recommend you to use .toggle() or the .show(),.hide() methods of jQuery. Just setting the css height property to zero is not a good practice.
Do you want to show the div when the page is loading or when its finished loading ( the DOM is ready) ?
Your JavaScript code would be:
$('#click-meopen').click(function() {
$('#this').show(); // or .toggle()
});
$('#click-meclose').click(function() {
$('#this').hide(); // or .toggle()
});
If you would use only one button you should use the .toggle() method, otherwise stick with the .show(),.hide() method !
When the DOM is ready ( The Page is loaded completely):
$(document).ready(function(){
$('#this').show();
});
documentation of the methods that are used:
http://api.jquery.com/show/
http://api.jquery.com/hide/
http://api.jquery.com/toggle-event/
http://api.jquery.com/ready/
I see that you have used -webkit-transition which works for me in chrome but i guess you want it to work in other browses than webkit.
There are two ways i can suggest, one is to just simply add -moz-transition: height 1s ease-in-out; and transition: height 1s ease-in-out; to do it with css3 but that wont help in older ie browsers.
An other way is to place a div inside your text in the div you want to collapse:
<div id="this">
<div id="height">
text
text
</div>
</div>
then in your javascript you can get the height of the inner div-element, and in that way you can use animate instead of height: auto.
$('#click-meopen').click(function() {
$('#this').animate({'height': $('#height').height()}, 1000);
});
$('#click-meclose').click(function() {
$('#this').animate({'height': 0}, 1000);
});
that should be enough for you.
$('#click-meopen').click(function() {
$("#this").css({'position':'absolute','visibility':'hidden','height':'auto'});
var newHeight = $("#this").height();
$("#this").css({'position':'static','visibility':'visible','height':'0'});
$('#this').css('height',newHeight + 'px');
});
$('#click-meclose').click(function() {
$('#this').css('height','0');
});
$('#click-meopen').click();
http://jsfiddle.net/XUjAH/100/