Opacity transition on page load does not kicks in on load - html

I want to have a very simple loading effect with a quick opacity change on the whole body. So I use the following CSS
body {
opacity: 0;
transition: opacity 2s;
}
body.show-page {
opacity: 1;
}
and add .show-page on load. Here is the live code http://plnkr.co/edit/Ze5TiqkZYiM41VJZVDuB?p=preview
For some reason it does not transition. After the page is loaded the transition works if I add/remove this class, but when loading, it does not happen. Any idea why?

Your script will run before body has finished loading as the script is inside the body tag.
You maybe want something like this:
function fadeIn() {
var body = document.getElementsByTagName('body')[0];
body.className += 'show-page';
}
window.onload = fadeIn;
Updated Plunker

One workaround can be to slightly delay (50ms) your JS doing so:
setTimeout(function(){body.className += 'show-page';}, 50);

Related

CSS transition for multiple elements on the page

On my page I have 2 divs:
<div class="mycards fight">
<div class="card"><span class="name"></span><div id="att1"><span></span></div><div id="def1"><span></span></div></div>
</div>
<div class="mycards fight2">
<div class="card"><span class="name"></span><div id="att2"><span></span></div><div id="def2"><span></span></div></div>
</div>
I am injecting dome text via jquery like:
$('#att1').html(sometext); $('#att2').html(sometext); etc.
In CSS I set the transition for these elements:
#att1, #att2, #def1, #def2 {
transition: all 1s ease;
}
The problem is, the transition is working only for second DIV, where #att2 and #def2 are present and it ignores it in my first DIV.
I also tried to do it via jquery :
$("#att1").addClass('trans');$("#def1").addClass('trans');
$("#att2").addClass('trans');$("#def2").addClass('trans');
in my script when it is needed, and then in CSS I defined just
.trans {
transition: all 1s ease;
}
but again, it works now only for the first DIV.
For some reason it can't do the same effect for both elemets. Not sure where is the problem.
Example where the transition is expected:
function bonus(val,val1,val2) {
$.ajax
({url: 'bonus.php',
data: {"var1": val,"var2": val1,"var3": val2},
type: 'get',
dataType: 'json',
success: function(datax) {
if (val2===1) {
if (val===1) {$("#att1").addClass('size-50');}
if (val===2) {$("#def1").addClass('size-50');}
if (val===3) {$("#att1").addClass('size-50');$("#def1").addClass('size-50');}
window.setTimeout(function(){
if (val===1) {$("#att1").removeClass('size-50'); $("#att1").addClass('size-30');}
if (val===2) { $("#def1").removeClass('size-50'); $("#def1").addClass('size-30');}
if (val===3) {$("#att1").removeClass('size-50'); $("#att1").addClass('size-30');
$("#def1").removeClass('size-50'); $("#def1").addClass('size-30');}
},500);
}
else {
if (val===1) {$("#att2").addClass('size-50')}
if (val===2) {$("#def2").addClass('size-50');}
if (val===3) {$("#att2").addClass('size-50');$("#def2").addClass('size-50');}
window.setTimeout(function(){
if (val===1) {$("#att2").removeClass('size-50'); $("#att2").addClass('size-30');}
if (val===2) { $("#def2").removeClass('size-50'); $("#def2").addClass('size-30');}
if (val===3) {$("#att2").removeClass('size-50'); $("#att2").addClass('size-30');
$("#def2").removeClass('size-50'); $("#def2").addClass('size-30');}
},500);
}
window.setTimeout(function(){runAll();},1000);
}});
}
Damn, I think the issue was in the conditions I had there using e.g. val===1 which wrongly compared the values. when I replaced it for == now it works for both cases.
Sometimes the core issue is caused by something else...

Are keyframe animations also rendered when not visible and do they consume resources?

I use a lot of CSS animations on my website but performance is not as good as it should be. Therefore I thougt maybe an infinite #keyframe animation which is only visible at sometimes slows the site down.
I hide it with opacity: 0 for fadeIn animation and after that I set display to none but I am not sure if the animation is rendered nevertheless and consumes resources.
An answer would be highly appreciated.
According to this w3c draft, no; the animation is terminated:
Setting the display property to none will terminate any running animation applied to the element and its descendants.
You can verify this by looking at which animation events are fired. We'll set up an infinitely alternating animation and then you can toggle the element's display with a button:
(d => {
const $ = d.querySelector.bind(d),
div = $("#test-div"),
button = $("#test-button"),
animationEvents = [
"animationstart",
"animationiteration",
"animationcancel",
"animationend",
],
animationEventHandler = e => console.log(e.type);
for (let animationEvent of animationEvents) {
div.addEventListener(animationEvent, animationEventHandler);
}
button.addEventListener("click", e => {
const lastDisplay = div.style.display || "block";
div.style.display = lastDisplay === "block" ? "none": "block";
e.target.textContent = "Toggle display: " + lastDisplay;
});
})(document);
#test-div {
padding: 30px;
animation: test-animation 1000ms alternate infinite steps(2, jump-none);
}
#keyframes test-animation {
from {
background-color: #0f0;
}
to {
background-color: #f00;
}
}
<button id="test-button" type="button">Toggle display: none</button>
<div id="test-div">test div</div>
You can see that animationiteration stops firing once the element is no longer displayed even though the animation is, "infinite." You could infer from this that the animation runs only while the element is displayed. Indeed, the animation is restarted from 0% when you show the element again.

Grey page content when side menu is opened

If you look at all the Google apps when you open the side (hamburger) menu the content of the app is greyed.
Here is an example
Is it possible to do this with ion-side-menu in ionic framework? If so, how?
Thank you.
Based on Mark Veenstra's answer, here is the result I came with.
In CSS:
.opaque-content {
opacity: .5;
transition: opacity 300ms ease-in-out;
}
In the controller I'm watching the open ratio of the side menu and set a flag:
$scope.$watch(
function () {
return $ionicSideMenuDelegate.getOpenRatio();
},
function (ratio) {
$scope.sidemenuopened = (ratio == 1);
});
In the template I'm using ng-class to conditionally apply the class:
<ion-side-menus>
<ion-side-menu-content ng-class="{'opaque-content' : sidemenuopened}">
<ion-nav-bar>
</ion-nav-bar>
</ion-side-menu-content>
</ion-side-menus>
This works and makes the page content partially transparent when the side menu is opened.
I believe this is not standard available in Ionic, but if you look at the $ionicModal you can see they do use the same technique there.
If you look at the CSS they use for this option, you should add the following to the correct class:
opacity: .5;
transition: opacity 300ms ease-in-out;
background-color: #000;
You should somehow detect when the side menu is exposed and then apply above CSS to the <ion-nav-view>.
I think you could create a directive or so which watches the $ionicSideMenuDelegate.isOpen() function and based on result apply or remove the CSS.
You only need CSS for this.
When the side menu is opened, there is a CSS class menu-open added to the body tag.
So just add the following and you will get what you want.
body.menu-open ion-side-menu-content {
-webkit-transition: opacity 300ms ease-in-out;
transition: opacity 300ms ease-in-out;
opacity: 0.5;
}
Based on Marius Bancila's answer, here is my solution.
In CSS: nothing
In the controller I'm watching the open ratio of the side menu and set a flag:
$scope.$watch(
function () {
return $ionicSideMenuDelegate.getOpenRatio();
},
function (ratio) {
$scope.sidemenuopened = (ratio == 1);
});
In the template I used modal backdrop background class instead of your opaque-content which isn't gray at all:
<ion-side-menus>
<ion-side-menu-content>
<div ng-class="{'modal-backdrop-bg' : sidemenuopened}"></div>
<ion-nav-bar>
</ion-nav-bar>
</ion-side-menu-content>
</ion-side-menus>
With this you will have the same effect as Google!

Fade transition

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!

Expand/Collapse Div

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/