How to get my .toggleClass() menu to work properly? - javascript

I am currently constructing a menu that consists of 2 hyperlinks, "Sign In" and "Sign Up". My goal is to have this menu work in such a way that when either hyperlink is clicked on, the appropriate div will appear below. For example, the user clicks on "Sign Up", then the "Sign up" form appears below. I have no issues with these <div>'s appearing, I have made a functioning script that uses the .slideToggle() function. Before I go any further, please view my website on a device with a screen size of 1400px or more, and click on both the "Sign Up" and "Sign In" hyperlinks. (http://www.codesrce.com)
If you noticed when you click on "Sign Up" or "Sign In", for the first click on each the text turns a greenish color, and then when you click on the other, it reverts back to white, and the one you most recently clicked on turns green. The problem is, what I am looking for is not working. It works for a brief moment, then gets messed up when you click them more than 3 times. Here is my question:
How can I make this menu work in a way that when either "Sign Up" or "Sign In" is clicked on, it changes the font color, but also when that same link is clicked again, or another the other link is clicked on, it reverts back to its original color, leaving that newly clicked link with a new text color until that one is clicked again or the other link is clicked on? I hope I am making sense. I will provide my code so far, and hopefully someone can help me out!
Basicaly, If one hyperlink is active with the greenish color, then the other one should be non-active with the white font color, and if neither one is active, then have both be white.
Colors
Greenish: #4AE6AB
White: (Obviously) #fff or white
Code
HTML:
<div id="BottomTop">
<div id="UserMenuBar">
<a class="ToggleSignInForm">Sign In</a><a class="ToggleSignUpForm">Sign Up</a>
</div>
</div>
<div class="SignInFormToggled" id="SignInForm">
<form id="signinform" onsubmit="return false;">
</form>
</div>
<div class="SignUpFormToggled" id="SignUpForm">
<form name="signupform" id="signupform" onsubmit="return false;">
</form>
</div>
CSS:
#SignInForm {
background: rgb(154,234,204);
height: 120px;
}
#SignUpForm {
background: rgb(154,234,204);
height: 120px;
}
.SignInFormToggled {
display: none;
}
.SignUpFormToggled {
display: none;
}
.ForgotPasswordFormToggled {
display: none;
}
#BottomTop {
background: #333333;
height: 40px;
width: 100%;
margin: 0px;
}
#UserMenuBar {
background: #333333;
/* Old browsers */
height: 40px;
width: 1400px;
margin-left: auto;
margin-right: auto;
line-height: 40px;
font-family: 'Gotham Rounded Book', Myraid Pro, Segoe UI, Helvetica Neue, Arial;
}
#UserMenuBar a {
padding-top: 30px;
padding-right: 20px;
color: #fff;
font-size: 16px;
-webkit-transition: color 0.3s ease;
-moz-transition: color 0.3s ease;
-ms-transition: color 0.3s ease;
transition: color 0.3s ease;
}
#UserMenuBar a:hover {
color: #4AE6AB;
cursor: pointer;
}
#UserMenuBar a.active {
color: #4AE6AB;
}
#UserMenuBar a.notactive {
color: #fff;
}
#SignInFormContainer {
width: 1400px;
height: 120px;
margin-left: auto;
margin-right: auto;
}
#SignUpFormContainer {
width: 1400px;
height: 120px;
margin-left: auto;
margin-right: auto;
}
JS:
$(function () {
$('.ToggleSignInForm').click(function () {
$('.SignInFormToggled').slideToggle();
$('.SignUpFormToggled').css("display", "none");
$(this).toggleClass('active');
if ($('.ToggleSignUpForm').hasClass('active')) {
$('.ToggleSignUpForm').toggleClass('notactive');
} else {}
});
});
$(function () {
$('.ToggleSignUpForm').click(function () {
$('.SignUpFormToggled').slideToggle();
$('.SignInFormToggled').css("display", "none");
$(this).toggleClass('active');
if ($('.ToggleSignInForm').hasClass('active')) {
$('.ToggleSignInForm').toggleClass('notactive');
} else {}
});
});
$(function () {
$('.ToggleForgotPasswordForm').click(function () {
$('.ForgotPasswordFormToggled').slideToggle();
});
});

Code Cleanup:
Your div's are mismatched. You have more closing tags for div than opening tags.
Also, you can get rid of the else statement if it is blank. You don't have to have an else statement if it is not needed.
You have three DOM document.ready functions but you just need one.
Solution:
Change:
$('.ToggleSignUpForm').toggleClass('notactive');
To:
$('.ToggleSignInForm').toggleClass('notactive');
$('.ToggleSignInForm').toggleClass('active');
UPDATE
Add:
$('.active').removeClass('active');
Before:
$(this).toggleClass('active');
JSFiddle Demo

The problem lies in the classes. In css, the last listed class overrides all previous classes for the elements involved. After you click a few times, the notactive class ends up at the end and overrides the active class. To solve this, simply toggle the active class when you toggle the notactive class. This makes sure only one of these classes is implemented at any given time, and will solve the problem.
The JS will look like this:
$(function () {
$('.ToggleSignInForm').click(function () {
$('.SignInFormToggled').slideToggle();
$('.SignUpFormToggled').css("display", "none");
$(this).toggleClass('active');
if ($('.ToggleSignUpForm').hasClass('active')) {
$('.ToggleSignUpForm').removeClass('active').addClass('notactive');
} else {}
$('.active').removeClass('active');
});
});
$(function () {
$('.ToggleSignUpForm').click(function () {
$('.SignUpFormToggled').slideToggle();
$('.SignInFormToggled').css("display", "none");
$(this).toggleClass('active');
if ($('.ToggleSignInForm').hasClass('active')) {
$('.ToggleSignInForm').removeClass('active').addClass('notactive');
} else {}
$('.active').removeClass('active');
});
});

I found an answer. Javascript is weird sometimes, but this code works!
Thank you #imbondbaby and others for leading me in the right direction.
JS:
$(function () {
$('.ToggleSignInForm').click(function () {
$('.SignInFormToggled').slideToggle();
$('.SignUpFormToggled').css("display", "none");
$(this).toggleClass('active');
if ($('.ToggleSignUpForm').hasClass('active')) {
$('.ToggleSignUpForm').toggleClass('notactive');
$('.ToggleSignUpForm').toggleClass('active');
}
if ($('.ToggleSignUpForm').hasClass('notactive')) {
$('.ToggleSignUpForm').toggleClass('active');
}
if ($('.ToggleSignUpForm').hasClass('notactive')) {
$('.ToggleSignUpForm').toggleClass('active');
$('.ToggleSignUpForm').toggleClass('notactive');
}
if ($('.ToggleSignUpForm').hasClass('active')) {
$('.ToggleSignUpForm').toggleClass('notactive');
}
});
$('.ToggleSignUpForm').click(function () {
$('.SignUpFormToggled').slideToggle();
$('.SignInFormToggled').css("display", "none");
$(this).toggleClass('active');
if ($('.ToggleSignInForm').hasClass('active')) {
$('.ToggleSignInForm').toggleClass('notactive');
$('.ToggleSignInForm').toggleClass('active');
}
if ($('.ToggleSignInForm').hasClass('notactive')) {
$('.ToggleSignInForm').toggleClass('active');
}
if ($('.ToggleSignInForm').hasClass('notactive')) {
$('.ToggleSignInForm').toggleClass('active');
$('.ToggleSignInForm').toggleClass('notactive');
}
if ($('.ToggleSignInForm').hasClass('active')) {
$('.ToggleSignInForm').toggleClass('notactive');
}
});
});
FIDDLE

Related

How do I change my navbar's height based on whether a link is in focus?

I'm using React and javascript to style my webpage, and I have implemented a skip link in my navbar that takes the user further down the page when clicked. This skip link only comes into focus when the user hits the tab key, but it is positioned above the site logo in the navbar and so needs more space when it is visible. I want to increase the height of my navbar when the link is visible, and right now I am using a boolean called linkHasFocus (for some conditional CSS styling), along with a function called checkFocus, to do that:
const TopNavbar = styled. div`
...
height: ${props => (props.linkHasFocus ? '9rem' : '4rem')};
...
`;
And here's the checkFocus function:
const checkFocus = () => {
const elem = document.getElementById('skip-link');
if (elem === document.activeElement) {
this.linkHasFocus = true;
}
this.linkHasFocus = false;
return this.linkHasFocus;
};
I then pass this to my TopNavbar component (which is the parent of my skip link component) in my return function like so:
<TopNavbar linkHasFocus={checkFocus}>
But it seems the checkFocus function isn't updating the linkHasFocus variable correctly. My understanding of props and javascript in general is a little shaky, so apologies if there's glaring issues here.
I've got this navbar example from w3schools.com (I suggest you to check the Top Navigation tutorial), and I've extended it with 3 examples, showing how you can expand it with JavaScript and CSS.
By using the property .classList we can .add(), .remove() or .toggle() classes from elements. Then we can add some style content to enhance them (by adding a different height and a transition for the topnav, for example) when a certain action is performed.
The following JavaScript snippet shows 3 examples:
expand the Navbar while we are pressing TAB key (keyCode == 9), and shrink it while that key is up;
toggle the expand when the SPACE key (keyCode == 32) is pressed;
expand the Navbar while the mouse is hovering the Skip section, and shrink it while the mouse leaves the area.
// example 1: expand the navbar while tab key is pressed
document.body.addEventListener("keydown", function(e) {
if(e.keyCode == 9) {
document.getElementById("myTopnav").classList.add("expand");
}
});
document.body.addEventListener("keyup", function(e) {
if(e.keyCode == 9) {
document.getElementById("myTopnav").classList.remove("expand");
}
});
// example 2: toggle navbar expand with space key
document.body.addEventListener("keydown", function(e) {
if(e.keyCode == 32) {
document.getElementById("myTopnav").classList.toggle("expand");
}
});
// example 3: expand the navbar while the mouse is over
document.getElementById("skip").addEventListener("mouseover", function(e) {
document.getElementById("myTopnav").classList.add("expand");
});
document.getElementById("skip").addEventListener("mouseout", function(e) {
document.getElementById("myTopnav").classList.remove("expand");
});
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
.TopNavbar {
height: 4rem;
overflow: hidden;
background-color: #333;
-webkit-transition: all .5s ease;
transition: all .5s ease;
}
#myTopnav.expand {
height: 9rem;
transition: height 300ms;
}
.TopNavbar a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
.TopNavbar a:hover {
background-color: #ddd;
color: black;
}
.TopNavbar a.active {
background-color: #04AA6D;
color: white;
}
.pageContent {
padding: 14px 16px;
}
li {
margin: 10px 0;
}
<html>
<head>
</head>
<body>
<div class="TopNavbar" id="myTopnav">
Home
Contact
About
<a id="skip" href="#skip">Skip</a>
</div>
<div class="pageContent">
<h3>Navbar extension example</h3>
<ul>
<li>Example 1: extend the navbar while <code>TAB</code> key is pressed.</li>
<li>Example 2: press <code>SPACE</code> key to toggle the navbar extend.</li>
<li>Example 3: extend the navbar while the mouse is over "Skip" option.</li>
</ul>
</div>
</body>
</html>
If that still isn't what you're looking for, you could have a look at CSS Selectors and search if there's something that suits your page.

How to make a box transition smoother in html?

I've been trying to find some information about this, but I cant find some good information.
I want to make a div, that says "Contact Us" and when you click on the div, a layer shows up smoothy with input types.
I know that I can make some quick javascript to change from display:none to display:block, but how can I do it smooth?
for an example (just a quick example, the actual one will be better)
<div id="contact-us" onClick="showContactUs()">
<div id="contact-us-content" style="display: block;">
Name - <input type="text" name="name">
Email- <input type="text" name="email">
</div>
</div>
And then javascript is
function showContactUs(){
var r = document.getElementById("contact-us-content");
r.style.display = "block";
}
If any of you have any tips, or a link I can check I would appreciate it.
I am not that good with jquery, but can absolutely try some if you think its better.
There is no way to make the appearing smooth by setting display: block. You can, however, transition opacity. I suggest adding a class by javascript and solving the rest by css.
Check it out here: https://jsfiddle.net/3wLrfk3d/
$(document).on('click', '#contact-us', show_contact_form)
function show_contact_form () {
$('#contact-us-content').addClass('shown')
}
css:
#contact-us-content {
opacity: 0;
transition: opacity .5s ease;
&.shown {
opacity: 1;
}
}
My example uses jquery and sass, I am sure you will be able to rewrite it to vanilla and css.
I usually transition the opacity, but that will mean the element will be there even if it's invisible, taking up space and blocking mouse events. I solve this by having two classes, one to fade the element and one to hide it completely when it's done fading out:
$(function() {
var $box = $('.box');
$('.toggle').on('click', function() {
if (!($box).hasClass('visible')) {
$box.addClass('transitioning');
setTimeout(function() {
$box.addClass('visible');
}, 1)
} else {
$box.removeClass('visible');
setTimeout(function() {
$box.removeClass('transitioning');
}, 400)
}
})
})
body {
font-family: Helvetica, Arial, sans-serif;
}
.box {
background-color: #333;
color: white;
border: 5px solid white;
padding: 50px 10px;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, .4);
text-align: center;
transition: opacity .4s ease-in-out;
display: none;
opacity: 0;
}
.transitioning {
display: block;
}
.visible {
opacity: 1;
}
.toggle {
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="toggle">Toggle Box</button>
<div class="box">
<h1>Hi there</h1>
</div>
Note: this is a quick and dirty example, it kinda freaks out if you spam clicks on the toggle button, I'll leave that up to you.

Sliding div out with css and jquery without triggering scrollbar?

I've been wrestling with this for way too long.
Problem: I'm trying to make the image slide off of screen when the button is pressed, which I have successfully done, but not adequately. There are two problems:
I don't want to hide overflow on the body to hide the horizontal scroll being triggered when the div moves off the screen.
When I click on the button for a second time, I want the div to slide in from the right back to the original position. I haven't been able to figure this one out. I know I can do it, but creating another css class, but I know there has to be an easier way.
JSFiddle
CSS:
#abs {
position: absolute;
height: 200px;
width: 200px;
background-color: grey;
left: 0;
top:0;
transition: transform 3s;
}
.open {
transform: translateX(1050px);
}
.hide {
display: none;
}
p {
text-align: center;
}
JS:
$('#clickMe').on('click', function(){
$('#abs').toggleClass('open');
if($("#abs").hasClass("open")) {
setTimeout(
function() {
$("#abs").hide();
},
2500);
} else {
$("#abs").show();
}
})
Hi Please refer to the fiddle.https://jsfiddle.net/cdx7zeo2/1/
I modified your code to use jQuery animate.
$('#clickMe').on('click', function(){
var right = parseInt($('#abs').css('left'));
console.log(right);
if(right === 0){
$( "#abs" ).animate({
left:'2500px'
}, 1500);
}else{
$( "#abs" ).animate({
left:'0px'
}, 1500);
}
})
Also modified the id test to have overflow-y hidden, so that you don't need to tough overflow property of body. Note, here we are not using open class anymore.
#test {
position: relative;
height: 500px;
width: 500px;
background-color: black;
overflow-y:hidden;
}

Change background color of div using conditional statement

I have 2 divs side by side and by default one is hidden and one is visible.
I have a jQuery function which, when mouseenter the visible div, the hidden one shows. And when mouseenter again, it becomes hidden again. (This is for a login box)
However - I want the always visible div (the mouseenter target) to change color depending on what state the toggled div is in. So far, I can get it to change color upon first mouseenter but it won't change again after that.
Here is the code I have so far:
<script>
$(document).ready(function () {
$("#loginBox").hide();
$("#sideBar").show();
$('#sideBar').mouseenter(function () {
$("#loginBox").toggle("slide");
if ($('#loginBox').is(":visible")) {
$("#sideBar").css("background-color","blue");
} else if ($('#loginBox').is(":hidden")) {
$("#sideBar").css("background-color","yellow");
}
});
});
</script>
So it starts off in its default color (grey by the style sheet) and when mouseenters it loginBox becomes visible and the sideBar turns blue. But when mouseenters again, even though loginBox becomes hidden, the sideBar remains blue.
JSFiddle
You can put the check in the complete function of toggle
$(document).ready(function() {
$("#aside").hide();
$("#asidebar").show();
$('#asidebar').mouseenter(function() {
$("#aside").toggle("slide", function() {
var onOrOff = $('#asidebar').css("background-color");
if ($('#aside').is(":visible")) {
$("#asidebar").css("background-color", "blue");
} else if ($('#aside').is(":hidden")) {
$("#asidebar").css("background-color", "yellow");
}
});
});
});
#asidebar {
float: right;
/* top: -205px; */
position: relative;
/*
Editing purposes */
background-color: rgba(120, 120, 120, 0.5);
width: 25px;
/*min height of container */
height: 400px;
margin: 5px;
padding: 1px;
font-family: helvetica;
}
#aside {
float: right;
/* top: -205px; */
position: relative;
/*
Editing purposes
background-color: blue; */
width: 250px;
border-left-style: dashed;
border-color: rgba(120, 120, 120, 0.5);
/*min height of container */
margin: 5px;
padding: 0;
font-family: helvetica;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="asidebar">Mouse Over</div>
<div id='aside'>Slide box</div>
You are better off putting the styles on a class and toggling that instead. Something like
...
$('#sideBar').mouseenter(function () {
$("#loginBox").toggle("slide");
$("#sideBar").addClass("semanticallyNamedClassForBlue");
$("#sideBar").toggleClass("semanticallyNamedClassForYellow");
});
...
CSS:
#sideBar.semanticallyNamedClassForBlue {background: blue}
#sideBar.semanticallyNamedClassForYellow {background: yellow}
as per this jsfiddle adapted from user3787555's http://jsfiddle.net/3rQNb/3/
Explanation:
On load the sidebar is grey.
on first hover both the yellow and blue classes are added to the element, but as the yellow class is last in the css source, it wins the cascade.
on next hover, the yellow class is removed, so the blue now wins.
I added the id to the css rule to get the specificity up enough - as you know a #id beats a .class in the cascade
If you want to learn more, A List Apart's CSS articles and Remy Sharp's JQuery for designers may give you some joy. If you want to learn more on specificity look at star wars specificity super awesome

How to make a div appear when hyperlink is clicked once and disappear when hyperlink is clicked a second time? Can this be repeated?

I am looking for a way to have a div appear after the user clicks a hyperlink, and then have that same div disappear when the user clicks it again. Currently, the user is only able to have the div appear when the hyperlink is pressed, but when you click the hyperlink again, the div remains in it's "display: block;" state. Here is what I mean:
HTML
<a onclick="showDiv()" id="ShowAboutButton">What's This?</a>
<div id="About">
</div>
CSS
#ShowAboutButton {
text-align: center;
margin-top: 40px;
background-color: white;
border: none;
cursor: pointer;
font-family: "Lato Light";
font-size: 22px;
}
#About {
width: 900px;
height: 600px;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
background-color: gray;
display: none;
transition: height 2s;
}
Javascript
function showDiv() {
document.getElementById('About').style.display = "block";
}
If it is at all possible, can someone please show me how to give the user the ability to click the hyperlink and have the div slide in with a transition effect, and then when the hyperlink is clicked again have it slide back out with a transition effect? Any help would be much appreciated! Thank you in advance!
You can do this very easily with jquery slideToggle:
$("#ShowAboutButton").click(function(){
$("#About").slideToggle();
});
JSFIDDLE
$('#ShowAboutButton').click(function() {
$('#About').toggle();
});
Vanilla JavaScript :
var about = document.getElementById('About');
about.style.display='none';
document.getElementById('ShowAboutButton').addEventListener('click', function() {
//Toggling
if(about.style.display != 'block') {
return about.style.display='block';
}
about.style.display = 'none';
});
OOPS. Missed top of your code.
<a onclick="showDiv(document.getElementById('About'))" id="ShowAboutButton">What's This?
<div id="About">
</div>
function showDiv(obj) {
if(obj.style.display == "block"){
obj.style.display='none'
}
else(obj.style.display == "none"){
obj.style.display='block'
}
}

Categories