Trying to avoid jQuery--
I have a nav on my website that switches between a header and side-bar when the window is resized. I have some problems when I toggle the sidebar and then resize the page.
If I toggle the side-bar and resize the page, I have 2 problems:
If I toggle the side bar and expand the page, the side-bar space stays toggled with no way to collapse it.
The side-bar's content opacity will change to 0 unless I first collapse the side-bar, expand the page to a header, and then bring back to the side-bar state.
function toggleSidebar() {
document.getElementById("sidebar").classList.toggle('active');
document.getElementById("wrapper").classList.toggle('active');
}
var width = document.body.clientWidth;
function headerResize() {
width = document.body.clientWidth;
console.log("Width: " + width);
if (width > 783) {
document.getElementById("Header-to-Hamburger-slot").innerHTML = document.getElementById("java-header").innerHTML;
document.getElementById("java-footer-slot").innerHTML = document.getElementById("java-footer").innerHTML;
} else {
document.getElementById("Header-to-Hamburger-slot").innerHTML = document.getElementById("java-hamburger").innerHTML;
document.getElementById("java-sidebar-slot").innerHTML = document.getElementById("java-sidebar").innerHTML;
document.getElementById("java-footer-slot").innerHTML = document.getElementById("filler").innerHTML;
}
}
headerResize();
window.addEventListener("resize", function(event) {
headerResize();
})
#wrapper {
position: absolute;
width: 100%;
right: 0;
transition: all 300ms ease;
}
#wrapper.active {
position: absolute;
width: 100%;
right: 260px;
transition: all 300ms ease;
}
#sidebar {
position: absolute;
right: 0px;
width: 260px;
height: 100vh;
text-align: center;
transition: all 300ms ease;
opacity: 0;
}
#sidebar.active {
right: 0px;
transition: all 300ms ease;
opacity: 1;
}
So the issue was that the resizing the page would auto-toggle the side-bar content off, but it wouldn't toggle my page wrapper back to its original position.
I just had to add
function autoCollapse() {
if (document.getElementById("wrapper").classList.contains("active")) {
document.getElementById("wrapper").classList.toggle('active');
}
}
And then place it inside my event listener
Related
I want to add transitions to sticky header to my store. I want to stciky header to show from the top when the scroll is > 50. The scrollheader and coverheader classes works fine. But transitions not worked. The header just jumps to above as sticky header is enabled. The logo part is resized in sticky header by almost 80px than normal header.
Here is the code of Javascript.
(function enableStickyHeader() {
var stickyHeader = document.querySelector('header').dataset.sticky;
var scrollHeader = $("header.scrollheader");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 50 && stickyHeader == 'true') {
scrollHeader.removeClass('scrollheader').addClass("coverheader");
} else {
scrollHeader.removeClass("coverheader").addClass('scrollheader');
}
});
})();
And through css I am applying css transition property. I have tried to get the results by applying height and line height to headers. But that also not works.
.coverheader {
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
transition: all 0.3s;
position: fixed;
}
header {
width: 100%;
line-height: 50px;
top: 0;
z-index: 150;
}
.scrollheader {
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
transition: all 0.3s;
position: relative;
}
And Html code for the case is this.
<header class="header-section scrollheader" data-section-id="header" data-section-type="header-section" data-sticky="true">
<p>logo and menu is there</p>
</header>
For the effect you give to work, the values on which css is based must change.
I prepared the following example to give you an idea.
Please note: To make it easy to understand, I have slightly extended the animation time. And I made the background black and the header white.
(function enableStickyHeader() {
var stickyHeader = document.querySelector('header').dataset.sticky;
var scrollHeader = $("header.scrollheader");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 82 && stickyHeader == 'true') {
scrollHeader.removeClass('scrollheader').addClass("coverheader");
} else {
scrollHeader.removeClass("coverheader").addClass('scrollheader');
}
});
})();
html {
height: 10000px;
background: black;
}
html,
body {
padding: 0;
margin: 0;
}
.coverheader {
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
position: fixed;
bottom: 100%;
transform: translateY(100%);
}
header {
display: flex;
width: 100%;
line-height: 50px;
z-index: 150;
background: white;
}
.scrollheader {
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
position: relative;
transform: translateY(0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="header-section scrollheader" data-section-id="header" data-section-type="header-section" data-sticky="true">
<p>logo and menu is there</p>
</header>
I have a fiddle in which there are 4 tiles placed horizontally with some space in between.
Here is the CSS which I have used in order to place them horizontally.
.featured-block {
position: relative;
display: flex;
justify-content: space-between;
}
Problem Statement:
What I want to achieve for the 3rd/4th tile(image) in the fiddle is I want cross-fade (fade-in/fade-out) happen with them(3rd/4th image) at the 3rd position from the left.
I believe I need to add the following css codes with some modification in order to make that happen but I am not sure what
modification I need to make.
.featured-block__item {
position: absolute;
top: 0;
left: 0;
width: 100%;
opacity: 0;
transition: opacity 800ms ease; /* immediately start fading out when active class is lost */
}
.featured-block__item.featured-block__item-active {
opacity: 1;
}
you can use following css code
.featured-block {
position: relative;
display: flex;
width:100%;
overflow:hidden;
justify-content: space-between;
}
.featured-block__item:nth-last-child(2),
.featured-block__item:last-child{
opacity: 0;
transition: opacity 800ms ease; /* immediately start fading out when active class is lost */
}
img{
width:calc(100% / 3);
}
.featured-block__item:last-child{
position: absolute;
top: 0px;
right: 0px;
bottom:0px;
}
.featured-block__item:nth-last-child(2).featured-block__item-active,
.featured-block__item:last-child.featured-block__item-active {
opacity: 1;
}
I have a menu system where there are two hamburger menus. I'm trying to work out how to have JS trigger both instances of these menu icons. They both have all have the same classes.
I've tried adding a for loop, to loop through anything with the instance of the classes, but this didn't seem to work, and I'm going around in endless circles now.
With the code below I've kept the index number of the three menu bars in the first hamburger men at zero[0] so that you can see the desired effect of what happens when you click on the top hamburger menu.
I'd like it so that when I click on either hamburger menu the animation of the bars happens on both icons and the state of the blue box changes.
Any help would be amazing.
Codepen link is here: https://codepen.io/emilychews/pen/jwwVam
Code is below.
JAVASCRIPT
var container = document.getElementsByClassName('container')[0],
bar1 = document.getElementsByClassName('bar1')[0],
bar2 = document.getElementsByClassName('bar2')[0],
bar3 = document.getElementsByClassName('bar3')[0],
box = document.getElementsByClassName('box')[0],
openMenu = false; // used for toggle
container.onclick = function(){
if(openMenu === false) {
bar1.classList.add("bar1_open");
bar2.classList.add("bar2_open");
bar3.classList.add("bar3_open");
box.classList.add("changeBackground");
openMenu = true;
} else {
bar1.classList.remove("bar1_open");
bar2.classList.remove("bar2_open");
bar3.classList.remove("bar3_open");
box.classList.remove("changeBackground");
openMenu = false;
}
};
CSS
* {padding: 0; margin: 0;}
body {height: 200vh; font-family: arial;}
/* red square */
.container {
margin: 10px;
width: 100px;
height: 100px;
background: red;
padding: 0px;
position: relative;
}
/* properties for all menu bar lines */
.bar {
position: absolute;
height: 4px;
width: 60px;
background: blue;
left: 20px;
}
/* 1st menu line */
.bar1 {
position: absolute;
top: 28px;
margin: 0 auto;
transform-origin: top right;
transition: transform .5s;
}
/* 2nd menu line */
.bar2 {
position: absolute;
top: 48px;
margin: 0 auto;
transition: opacity 1s;
}
/* 3rd menu line */
.bar3 {
position: absolute;
top: 68px;
margin: 0 auto;
transform-origin: right bottom;
transition: transform .5s;
}
.bar1_open{
transform-origin: top right;
transform: rotate(-45deg) translate(-7px, -7px);
transition: transform .5s .1s ease-out ;
}
.bar2_open {
opacity: 0;
transition: opacity .2s ease-in;
}
.bar3_open {
top: 69px;
transform-origin: right bottom;
transform: rotate(45deg) translate(-7px, 7px);
transition: transform .5s .1s ease-out;
}
.box {
padding: 10px;
width: 200px;
height: 100px;
background: blue;
position: absolute;
left: 300px;
top: 30px;
z-index: 99;
color: white;
display: flex;
justify-content: center;
align-items: center
}
.changeBackground {
background: red;
}
HTML
<div class="container">
<div class="bar bar1"></div>
<div class="bar bar2"></div>
<div class="bar bar3"></div>
</div>
<!-- second hamburger menu button that currently has no JS -->
<div class="container">
<div class="bar bar1"></div>
<div class="bar bar2"></div>
<div class="bar bar3"></div>
</div>
<div class="box"> This toggles after 1st hamburger menu is clicked</div>
I have refined your code to work how you want it, i set the variables to the array of DOM Elements instead of the single one and for loop through them.
EDIT: heres the updated codepen if you'd like to take a look https://codepen.io/anon/pen/LLBEeQ
var container = document.getElementsByClassName('container'),
bar1 = document.getElementsByClassName('bar1'),
bar2 = document.getElementsByClassName('bar2'),
bar3 = document.getElementsByClassName('bar3'),
box = document.getElementsByClassName('box')[0],
openMenu = false; // used for toggle
for(var i=0; i < container.length; i++){
container[i].onclick = function(){
if(openMenu === false) {
for(var j = 0;j<bar1.length;j++){
bar1[j].classList.add("bar1_open");
bar2[j].classList.add("bar2_open");
bar3[j].classList.add("bar3_open");
}
box.classList.add("changeBackground");
openMenu = true;
} else {
for(var j = 0;j<bar1.length;j++){
bar1[j].classList.remove("bar1_open");
bar2[j].classList.remove("bar2_open");
bar3[j].classList.remove("bar3_open");
}
box.classList.remove("changeBackground");
openMenu = false;
}
}
};
If you are ok with using JQuery this works perfect:
HTML(link to jquery):
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
Javascript:
var container = document.getElementsByClassName('container')[0];
console.log(container);
var bar1 = document.getElementsByClassName('bar1')[0],
bar2 = document.getElementsByClassName('bar2')[0],
bar3 = document.getElementsByClassName('bar3')[0],
box = document.getElementsByClassName('box')[0],
openMenu = false; // used for toggle
$(".container").click(function(){
if(openMenu === false) {
$(".bar1").addClass("bar1_open");
$(".bar2").addClass("bar2_open");
$(".bar3").addClass("bar3_open");
box.classList.add("changeBackground");
openMenu = true;
} else {
$(".bar1").removeClass("bar1_open");
$(".bar2").removeClass("bar2_open");
$(".bar3").removeClass("bar3_open");
box.classList.remove("changeBackground");
openMenu = false;
}
});
I want to trigger a opacity transition. If an element is hovered by the cursor, the cursor shall fade out, change its background-image and then fade in again. I wanted to achieve that by adding and removing a css class. It's not working, what is wrong?
js fiddle
HTML
<div class="wrapper">
<div class="cursor">
</div>
<div id="grey">
</div>
</div>
CSS
.wrapper {
width: 100%;
height: 100%;
background-color: lightgrey;
padding: 60px;
cursor: none;
}
#grey {
width: 100px;
height: 100px;
background: grey;
}
.cursor {
position: fixed;
width: 20px;
height: 20px;
pointer-events: none;
opacity: 0;
-webkit-transition: opacity .3s; /* Safari */
transition: opacity .3s;
}
.red {
background: red;
opacity: 1;
}
.green {
background: green;
opacity: 1;
}
JS
$('.wrapper').on('mousemove', function(e){
$('.cursor').css('left', e.clientX-10).css('top', e.clientY -10);
if ($.contains($('.wrapper')[0], e.target)){
$('.cursor').removeClass('green').addClass('red');
}else{
$('.cursor').removeClass('red').addClass('green');
}
});
DEMO HERE
Ok, here you go. You need to keep track of 2 things here which you already achieved partially and also wait for fadeOut to complete and add a callback for adding and removing respective class
Whether cursor has entered element
Whether cursor has left element
Below is how you could actually do it.
var entered=false;//global variables to show the position of cursor
var left=false;
$('.wrapper').on('mousemove', function(e){
$('.cursor').css('left', e.clientX-10).css('top', e.clientY -10);
if ($.contains($('.wrapper')[0], e.target)){
if(!entered)
{
//just to do it once and not on every mousemove you need to check here whether
//it has already entered and moving inside the element
entered=true;
left=false;//to check the vice versa operation
$('.cursor').fadeOut('fast',function(){
//callback function after fadeOut completes
$(this).removeClass('green').addClass('red');
}).fadeIn('fast');
}
}else{
if(!left)
{
left=true;
entered=false;
//same goes here too
$('.cursor').fadeOut('fast',function(){
$(this).removeClass('red').addClass('green');
}).fadeIn('fast');
}
}
});
you have to change background color , not opacity ( opacity is always 1 )
CSS
.cursor {
position: fixed;
width: 20px;
height: 20px;
pointer-events: none;
opacity: 0;
-webkit-transition: background-color .3s; /* Safari */
transition: background-color .3s ;
}
.red {
background-color: red;
opacity: 1;
}
.green {
background-color: green;
opacity: 1;
}
So you said your question is wrong, it is "no, I just made it easier for hier, in reality it is an background image" - so you transition between two background-images.
Here is how you do it:
You can not do it with CSS transition in ONE element/div
You will have to make two divs wich one background each
Increase the zIndex of the div you want to fade out in by one
Fade out div, while the new div stays at opacity: 1
I need to do with an animation that is intially the image will be on full screen whenver i click on the screen it will popin an go to a div. for this i haved used te following code.
<div class="header_relative">
<header id="cover_photo_header" class="large">
<img></img>
</header>
</div>
styles:
<style>
header_relative
{
position:relative
}
header, a, img{
transition: all 2s;
-moz-transition: all 2s;
-webkit-transition: all 2s;
-o-transition: all 2s;
}
header.large
{
position: fixed;
top: 0;
left: 0;
width:100%;
height:100%;
overflow: hidden;
z-index: 19;
}
header.small
{
position: fixed;
overflow: hidden;
z-index: 19;
}
</style>
Javascript:
window.addEvent('click', function(){
$('global_content').getElement('header.large').style.width = '770px';
$('global_content').getElement('header.large').style.height = '300px';
$('global_content').getElement('header.large').style.margin = 'auto';
$('global_content').getElement('header.large').style.top = '-294px';
$('global_content').getElement('header.large').style.left = '29.1%';
setTimeout(function(){
//do what you need here
$('global_content').getElement('header').removeClass("large").addClass("small");
func, delay
}, 2000);
});
But he animation is changing on left.Can you guys help me howto come out of this