transition for addclass only works after first time - javascript

I basically have some social media icons at the top of the page, that later become fixed.
I want them to fade in, I was using CSS. Everything I tried using JS did the same thing or didn't work.
Here is my JS:
jQuery(document).scroll(function() {
var y = jQuery(document).scrollTop(), //get page y value
social = jQuery(".socialnetworks"),
headerHeight = jQuery(".bg-cover").height();
if(y >= headerHeight + 500) {
social.css({opacity : 0});
social.addClass("fixedsocialnetworks");
} else {
social.removeClass("fixedsocialnetworks");
}
});
And my CSS
.fixedsocialnetworks {
position: fixed!important;
top: 200px!important;
z-index:10;
left:30px;
opacity:1!important;
transition: opacity 400ms;
}
So I set the opacity to 0, then add a class that sets the opacity to 1, and has the transition.
So it works, but it doesn't work the first time on scroll, it works every other time after the first. Why? How do I fix this?

Related

Changing the size of the image in the sticky header when scrolling down

On the website (please don't share), in WordPress, I set a sticky header using CSS
header#masthead {
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10000;
}
This works correctly. However, the image in the header is too big, that's why I resized it with an animation when scrolling down
jQuery(document).ready(function() {
jQuery(function() {
var $nav = jQuery('#masthead .custom-logo');
var height_original = jQuery('#masthead .custom-logo').css("height").replace("px","");
var height_small = height_original * 0.666;
var width_original = jQuery('#masthead .custom-logo').css("width").replace("px","");
var width_small = width_original * 0.666;
jQuery(document).scroll( function() {
var value = jQuery(this).scrollTop();
if ( value > 0 ){
$nav.stop().animate({height:height_small,width:width_small},100);
} else if (value == 0 ) {
$nav.stop().animate({height:height_original,width:width_original},100);
}
});
});
});
But, it doesn't work properly.
I primarily use Opera GX, where it behaves like this - when scrolling down, the animation is slowed down. Also, if you just scroll down a little, the animation doesn't run all the way and the image goes back to its original size, scrolling up works without a problem.
The strange thing is that I've also tried it in Firefox, Chrome and Edge. It behaves differently in everyone, but nowhere does it work 100% correctly.
What is wrong with the code please?
Thank you
I think instead of that long jquery code you can use this simple javascript code with some css to get the results you want:
I hope this helps you to reach what you looking for :)
JS
// Add a class to the header when scrolling
let header = document.querySelector('header');
window.addEventListener('scroll' , function () {
let window_top = this.scrollY;
if (window_top == 0) {
header.classList.remove('resize');
}else {
header.classList.add('resize');
}
});
CSS
/* these are the default styles (when the user doesnt scroll down yet) */
header#masthead {
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10000;
transition: .3s;
}
header#masthead img{
transition: .3s; /*here i added transition to give the image a smooth animation*/
}
/* these are the styles when the user scrolls */
header#masthead.resize img{
height: 50px; /* <=== here i gived the image a smaller size */
}

jquery load callback function not working synchronously

Ok from looking previously I heard that I could use a callback function to make a jquery load function synchronous.
For context I'm trying to do a crossfading transition that is triggered from an onclick function. Basically I want to ensure that the content on bottom has loaded before the top starts going transparent but that doesn't always happen clearly, there is an image on them which quite clearly hasn't loaded by that time, is there a fix to ensure it waits?
Below is a simplified version of the code to show the issue. Help would be appreciated.
if (onTop === true) {
onTop = false;
$("#bottom").load(Location, function() {
setTimeout(function() {
if (onTop === false) {
document.getElementById("bottom_container").style.zIndex = 0;
}
}, 800);
document.getElementById("top_container").style.opacity = 0;
document.getElementById("bottom_container").style.height = null;
var bottomContainerHeight = document.getElementById("bottom_container").clientHeight;
document.getElementById("top_container").style.height = (bottomContainerHeight) + "px";
//Makes sure the top content is equal in height to the top content as to not overflow past it.
});
}
else {
onTop = true;
$("#top").load(Location, function() {
document.getElementById("bottom_container").style.zIndex = -2;
document.getElementById("top_container").style.opacity = 1;
document.getElementById("top_container").style.height = null;
var topContainerHeight = document.getElementById("top_container").clientHeight;
document.getElementById("bottom_container").style.height = (topContainerHeight) + "px";
//Makes sure the bottom content is equal in height to the top content as to not overflow past it.
});
}
You could accomplish this using CSS animations and/or transitions.
The z-index doesn’t matter in this case.
Since you’ll be fading the elements in and out, it doesn’t matter what layer they’re on.
#keyframes fade {
0% { opacity: 0; }
100% { opacity: 1; }
}
.fade-in {
animation: fade 500ms linear 0 1 normal forwards;
}
.fade-out {
animation: fade 500ms linear 0 1 reverse forwards;
}
Then you can just toggle the classes for each to get the effect.
document.querySelector("#top").classList.add("fade-out");
document.querySelector("#top").classList.remove("fade-in");
document.querySelector("#bottom").classList.add("fade-in");
document.querySelector("#bottom").classList.add("fade-out");
The images themselves can be preloaded.

CSS or JS transition for button that changes size from text changes?

I have an Angular app with a button that has a label of "+"
On mouse-over I call element.append(' Add a New Number'); This adds that text new to the + in the label.
Use clicks the button, new number is added, label of button is returned to "+"
I would like to animate the button size change and/or the txt label change. So far, just adding a css transition to width does nothing.
Thoughts?
UPDATE:
To help clarify, this is a bootstrap input group button. I don't want to set widths or css transforms, to avoid breaking the group either here or at other screen sizes.
here are the 2 states:
I was simply letting the existing button stretch due to the injection of more words.
I am probably guessing you don't have a predefined width. anyways you could use transform-origin and scale to achieve such an effect
FIDDLE HERE
HTML:
<button id="btn">Click</button>
CSS:
#btn {
outline: none;
border:none;
background: orange;
padding: 1em 1.5em;
-webkit-transition: .3s;
-o-transition: .3s;
transition: .3s;
}
#btn:hover {
-webkit-transform: scaleX(1.2);
-ms-transform: scaleX(1.2);
-o-transform: scaleX(1.2);
transform: scaleX(1.2);
-webkit-transform-origin:0 0;
-moz-transform-origin:0 0;
-ms-transform-origin:0 0;
-o-transform-origin:0 0;
transform-origin:0 0;
}
you should use CSS transforms for animations rather than a property like width. The animation is slightly jerky , so you might want to work on it a bit more.
You had jQuery tagged, so this is how I would do it.
All the transitions. fade + animate
function changeButtonText(button, text){
// jQuery it
$button = $(button);
// get orinal css'es
oooon = $button.css('text-align');
doooo = $button.css('overflow');
treee = $button.css('white-space');
$button.css('text-align', 'left').css('overflow', 'hidden').css('white-space', 'nowrap');;
// get new width first
$tmpBtn = $button.clone().append(text).css('opacity', '0.0').appendTo('body');
newWidth = $tmpBtn.outerWidth();
$tmpBtn.remove();
// now stretch the button out
$button.animate({width: newWidth+"px"});
// fade texts into the butt
$button.append('<span style="display:none">'+text+'</span>');
$btnText = $button.find('span').fadeIn('slow');
return {
'text-align':oooon,
'overflow':doooo,
'white-space':treee
};
}
Fiddle
I think that with bootstrap CSS and Angular - it will be more complex, but this is how I would go about it programatically. You'll have to deal with the model and the data differently - and you should probably build a directive to repeat the action and integrate with Angular smoothly:
HTML
<div class="thing">+ <span id="message">
<span id='target'></span>
</span></div>
JavaScript
$('.thing').hover( function() {
var originalWidth = $(this).outerWidth();
$messageHolder = $(this).find('#message');
$target = $(this).find('#target');
$target.text('Some helpful text');
var targetWidth = $target.outerWidth();
$messageHolder.animate({
width: targetWidth
}, {
duration: 200,
complete: function() {
$messageHolder.animate({
opacity: 1
}, 500);
}
});
});
$('.thing').on('click', function() {
$target = $(this).find('#target');
$target.empty();
$messageHolder = $(this).find('#message');
$messageHolder.animate({
opacity: 0
}, {
duration: 200,
complete: function() {
$messageHolder.animate({
width: 0
}, 200);
}
});
});
I'm sure that Angular's ng-animate library watches the dom and also has an excellent way of animating things as they change in the model/controller or whatever they are calling it. This is probably something what it looks like behind the scenes.
Good luck!
jsFiddle

How can I shrink a header animated when I scroll down and enlarge it when I scroll up?

I'm just going to build me a website. I thought it would be nice if my header is shrinking a litte bit when I'm scrolling down to 30px. Of course it should enlarge again when I'm scrolling up to the top. And thats my problem. I can not find out how I increase the header again! Here is my jQuery Code for the shrink effect:
$(document).ready(function() {
$(window).scroll(function() {
var top = $(document).scrollTop();
if (top > 30) {
$("#header").animate({height:50}, 200);
$("#header").animate({opacity:0.5}, 200);
$("#logoimage").animate({height:40}, 200);
$("#logoimage").delay(20).queue(function() { $(this).css({'margin-top':'20px'});
$(this).dequeue();});
}
})});
I've created a Page on JSFiddle that I can show what i mean: http://jsfiddle.net/Xuryon/s46zzkt2/
I hope somebody knows how to solve that Problem...
This should do it : http://jsfiddle.net/gmdxs42t/
$(document).ready(function() {
var fflag = true;
$(window).scroll(function() {
var top = $(document).scrollTop();
if (top > 30 && fflag) {
fflag = false; //Will stop re-entry on every px scrolled
$("#header").animate({height:50}, 200);
$("#header").animate({opacity:0.5}, 200);
}
if (top<30 && !fflag){ //Will occur when scroll reached top
fflag=true; //Will enable the above condition entry when top exceeds 30
$("#header").animate({height:100}, 200);
$("#header").animate({opacity:1}, 200);
}
})});
You could simply add a class to the body (or to the #header) and use a css transition for the animations:
http://jsfiddle.net/s46zzkt2/1/
js
if (top > 30) { $('body').addClass('foo'); }
else { $('body').removeClass('foo'); }
css
#header { -webkit-transition: all 0.5s ease; transition: all 0.5s ease; }
.foo #header { height: 50px; }

Resetting state of transition after the transition played

I have a message which I display on the screen when a user clicks on some links. I use a transition on the opacity to get the message to fade away.
The problem is that when a user clicks on the next link which is supposed to display the message, the element has its opacity set to 0 (thus it's not visible).
The opacity transition is triggered by a JavaScript function.
My question: would it be possible to reset the opacity (back to 1) before the transition effect happens?
I only see a nasty way such as triggering a function from within the function that triggers the opacity transition, to reset the opacity back to 1. Something like:
setTimeout(function(){elem.style.opacity = 1;)}, 3000);
But this is not great because I'd like the opacity to be reset as soon as a user clicks another link for which this message is displayed.
ideas?
EDIT:
Fiddle
HTML:
<div id="pop_up" class="pop_up">negative</div>
<a class="something_else" href="#" onclick="show(event, this); return false;">toto</a>
<a class="something_else" href="#" onclick="show(event, this); return false;">titi</a>
CSS:
.pop_up
{
position: absolute:
top: -10px;
padding: 10px;
background-color: orange;
opacity: 1;
transition: opacity 1s linear;
}
JS:
function show(e, elem)
{
msg = document.getElementById("pop_up");
msg.style.top = elem.offsetTop;
msg.style.left = elem.offsetLeft;
msg.style.opacity = 0;
msg.innerHTML = "Hug Me!";
}
I think I know what you want. You need to reset the transition to none and back again each time, and also reset the opacity each time and hide/show. Using the following CSS:
.pop_up
{
position: absolute;
display: none;
padding: 10px;
background-color: orange;
}
and the following javascript:
function show(e, elem) {
var msg = document.getElementById("pop_up");
msg.style.transition = 'none';
msg.style.display = 'none';
msg.style.opacity = 100;
msg.innerHTML = "Hug Me!";
msg.style.display = 'block';
msg.style.top = '' + elem.offsetTop + 'px';
msg.style.left = '' + elem.offsetLeft + 'px';
msg.style.transition = 'opacity 2s linear';
msg.style.opacity = 0;
}
I think you get the effect you want. I have changed to a 2s transition to see ity better, that you can adjust. The point is to hide and reset the popup each time, then reset the transition and show so that the transition runs again.
I have made msg a local vairable (with the vardeclaration) but also agree with the comments that using global functions and inline event handlers like this is not ideal. Improvments to that depnd on if you want to use a js library and if so which or if you want to stick to pure js.
Working fiddle (only tested in Firefox).
This technique stopped working with me, until I nailed done what actually make it work. It's necessary to keep this line in the JS code:
msg.style.bottom = elem.offsetTop + 'px';
If you remove it, it seems like the CSS for the element is not re-evaluated, which means the transition is actually not reset from 'none' to 'opacity 1s ease' for instance, which actually triggers the transition. So, if you remove the lines that actually reset the position of the div, the css won't be re-evaluated. In my case, I ended up needing the element to have a fixed position. So I first do:
msg.style.bottom = elem.offsetTop + 'px';
Immediately followed by:
msg.style.bottom = 0;
The first call internally forces the transition to be reset from none to something else, and then of course I finally positioned the element where I want.
Note that the first line might as well be:
var tmp = elem.offsetTop;
What's important here, is to change the state of the element, so that its CSS is being internally re-evaluated by the browser engine.

Categories

Resources