Custom Dropdown menu not working with links - javascript

I'm trying to make a custom menu using a tutorial I found.
The problem I'm running into is not the implementation, but something that stops me from clicking through links. When, I have the menu "opened" and when I click on a say link, it just closes the menu and for a quick second I see it highlight the whole box instead of the link.
Here are a few screenshots. You can hover over the links (they turn purple when hovered), but when you click on an individual link it tends to just click out of the whole menu instead of sending you to the said page. But when, I hover over it I can see that it is showing the link in the bottom left hand corner of my browser. I just can't seem to figure out what is happening with the click out instead of the url sending you to the page.
http://cl.ly/image/0S2F2c3h3g1o
(hover screen shot)
http://f.cl.ly/items/3P1h27323B203E2J0N41/clickout.png
(clickout)
When I try to click on any link, I just get this blue box, and it closes the menu instead of sending you to the linked page.
This is the HTML that I have hooked up
<!-- MOBILE MENU / -->
<nav id="mobile-menu">
<div id="mobmenu" class="dropdown-menu" tabindex="1">
<ul class="dropdown" tabindex="1">
<li>ABOUT</li>
<li>WORK</li>
<li>NOTES</li>
</ul>
</div>
</nav>
<!-- / MOBILE MENU -->
This is the Javascript.
function DropDown(el) {
this.dd = el;
this.opts = this.dd.find('ul.dropdown > li');
this.val = '';
this.index = -1;
this.initEvents();
}
DropDown.prototype = {
initEvents : function() {
var obj = this;
obj.dd.on('click', function(event){
$(this).toggleClass('active');
return false;
});
obj.opts.on('click',function(){
var opt = $(this);
obj.val = opt.text();
obj.index = opt.index();
});
},
getValue : function() {
return this.val;
},
getIndex : function() {
return this.index;
}
}
$(function() {
var dd = new DropDown( $('#mobmenu') );
$(document).click(function() {
// all dropdowns
$('.dropdown-menu').removeClass('active');
});
});
</script>
And the CSS.
#mobile-menu {
width: 320px;
}
.dropdown-menu {
background: #050607 url(images/menu_closed.png) no-repeat center top;
border: none;
color: #FFF;
cursor: pointer;
height: 50px;
font-weight: bold;
margin-top: 17px;
outline: none;
position: fixed;
-webkit-appearance: none;
width: 320px;
z-index: 9999;
}
.dropdown-menu::after {
content: "";
width: 0;
height: 0;
position: absolute;
right: 16px;
top: 50%;
margin-top: -6px;
}
/* ACTIVE STATE */
.dropdown-menu .dropdown {
background: #050607;
height: 1000px;
list-style: none;
overflow: hidden;
pointer-events: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
opacity: 0.0;
}
.dropdown-menu .dropdown li {
position: relative;
top: 10px;
z-index: 99;
}
.dropdown-menu .dropdown li a {
border-top: 1px solid #1f1f1f;
color: #FFF;
display: block;
font-family: 'Open Sans', sans-serif;
font-size: 30px;
font-weight: 200;
letter-spacing: 8px;
pointer-events: visible;
padding: 15px 25px 15px 25px;
text-align: center;
text-decoration: none;
z-index: 9999999999999999999999;
}
.dropdown-menu .dropdown li:nth-child(5) {
font-size: 15px;
font-weight: 100;
letter-spacing: 2px;
text-align: center;
}
.dropdown-menu .dropdown li:hover a { background: #050607; color: #605e90; }
.dropdown-menu.active .dropdown {
-moz-animation: fadein .3s linear;
-webkit-animation: fadein .3s linear;
-ms-animation: fadein .3s linear;
animation: fadein .3s linear;
pointer-events: auto;
opacity: 1.0;
z-index: 999999 !important;
}
.dropdown-menu.active:active {
pointer-events: auto;
}
.dropdown-menu.active::after {
border-color: #000;
margin-top: -3px;
}
.dropdown-menu.active {
background: #050607 url(images/menu_open.png) no-repeat center top;
outline: none;
}
Thanks! :3

After the obj.opts click event handler fires, the obj.dd click event handler will also fire. To prevent this, call the stopPropagation function of the event object passed to the handler.
See here for a working example: http://jsfiddle.net/hwTUZ/1/

Related

Whatsapp active chat list item animation

I was wondering if there is an easy way of creating the animation, similar to Whatsapp one.
When you are on chat screen and go back to chat list, an active element is highlighted gray for a moment (so it shows which chat was opened before).
Is there not complicated way of doing this in JS or CSS? Hopefully most of you guys know what I'm talking about. Unfortunately can't find any examples in the net...
Here is a example of how you could achieve the effect, but with no more details on your project i can't do more.
var li = $('li');
var messages = $('.messages');
var close = $('.close');
li.on('click', function(){
$(this).addClass('active');
messages.addClass('active');
});
close.on('click', function(){
messages.removeClass('active');
li.removeClass('active');
});
html,
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.info {
margin-bottom: 20px;
padding-left: 15px;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
background: #ececec;
padding: 10px;
border-bottom: 2px solid black;
cursor: pointer;
transition: background .2s .3s;
}
li.active {
background: gray;
transition: background .3s;
}
.messages {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
transition: transform .3s;
transform: translateX(100%);
padding: 20px;
}
.messages.active {
transform: translateX(0);
}
.close {
display: inline-flex;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
position: absolute;
right: 70px;
top: 30px;
background: black;
color: white;
border-radius: 50%;
font-size: 20px;
cursor: pointer;
}
.close:hover {
opacity: .7;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="info" >Click on a person, and close the discussion by clicking on the "X" to see the effect.</p>
<ul>
<li>Bob</li>
<li>Steven</li>
<li>Marie</li>
<li>Marc</li>
<li>Jack</li>
<li>Edouardo</li>
</ul>
<div class="messages">
A lot of messages bla bla ...
...
<span class="close">X</span>
</div>

jQuery toggleClass fade works with one class, not with the other?

I want my i elements to lose the outline class on hover, but for some reason this is not working. The class is lost and added again instantly without a fade/delay. If I try this exact same code with a class of background then it does work. What am I not seeing here?
The second problem is that when I do try this with a background class, the background stays there for the duration of the fade (in this case 500ms) and then disappears instantly. This should also be a fade, like a fade out.
Thank you!
JSFiddle
$('nav a').hover(function(){
if (!$(this).find("i").hasClass("home")){
$(this).find('i').toggleClass('outline', 500);
}
})
.hover() can be passed 2 functions as arguments. The first is like .mouseover() and the second is the .mouseout()
$('nav a').hover(function() {
$(this).find('.home').removeClass('outline');
}, function() {
$('.home').addClass('outline');
})
Update
You can add fadein and fadeout effect without Javascript, only with css:
nav {
font-size: 20 px;
}
nav a {
padding-left: 30 px;
}
nav a i {
position: absolute;
left: 0;
}
nav a i.star: not(.outline) {
opacity: 0;
transition: opacity 300 ms ease;
}
nav a: hover.star: not(.outline) {
opacity: 1;
transition: opacity 300 ms ease;
}
Demo here.
With the help of [Radonirina Maminiaina][1]'s answer and some altering of the code by myself I made it work exactly as intended.
It was Radonirina's idea to put the second icon right behind the original icon by using position: absolute; (see his code above), but then I came up with the idea to add the class "dark" to the hidden icon underneath and simply select it to make the opacity 0, and 1 on hover, including the transition effect. This made the CSS a lot simpler and it works beautifully.
Thanks again!
Here is a working example of the end result:
$('.menu-toggle').click(function() {
$('nav').toggleClass('nav-open', 500);
$(this).toggleClass('open');
})
#import url('https://fonts.googleapis.com/css?family=Fjalla+One');
/* Navigation bar */
header {
position: fixed;
height: 50px;
width: 100%;
background: #666666;
}
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav a {
color: #222;
text-decoration: none;
text-transform: uppercase;
font-weight: 600;
font-size: 1rem;
font-family: Fjalla One;
}
.smallNav {
position: absolute;
top: 100%;
right: 0;
background: #CCCCCC;
height: 0px;
overflow: hidden;
}
.nav-open {
height: auto;
}
.smallNav a {
color: #444;
display: block;
padding: 1.5em 4em 1.5em 3em;
border-bottom: 1px solid #BCBCBC;
}
.smallNav a:last-child {
border-bottom: none;
}
.smallNav a:hover,
.smallNav a:focus {
color: #222;
background: #BABABA;
}
/* Menu toggle */
.menu-toggle {
padding: 1em;
position: absolute;
right: 1em;
top: 0.75em;
cursor: pointer;
}
.hamburger,
.hamburger::before,
.hamburger::after {
content: '';
display: block;
background: white;
height: 3px;
width: 1.5em;
border-radius: 3px;
}
.hamburger::before {
transform: translateY(-6px);
}
.hamburger::after {
transform: translateY(3px);
}
.open .hamburger {
transform: rotate(45deg);
}
.open .hamburger::before {
opacity: 0;
}
.open .hamburger::after {
transform: translateY(-3px) rotate(-90deg);
}
.menu-toggle:hover {
transform: scale(1.1);
}
i.icon {
margin-right: 0.5em !important;
font-size: 1.2em !important;
}
/* Change icons on hover */
nav a i.dark {
position: absolute;
left: 42px;
}
nav a i.dark {
opacity: 0;
transition: opacity .25s ease;
}
nav a:hover i.dark {
opacity: 1;
transition: opacity .25s ease;
}
nav a:hover i.outline {
opacity: 0;
transition: opacity .25s ease;
}
<!DOCTYPE html>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<header>
<div class="header-container">
<nav class="smallNav">
<ul>
<li><i class="icon home"></i>Home</li>
<li><i class="icon star outline"></i><i class="icon star dark"></i>Featured</li>
<li><i class="icon newspaper outline"></i><i class="icon newspaper dark"></i>News</li>
<li><i class="icon user outline"></i><i class="icon user dark"></i>Career</li>
<li><i class="icon envelope outline"></i><i class="icon envelope dark"></i>Contact</li>
</ul>
</nav>
<div class="menu-toggle">
<div class="hamburger">
</div>
</div>
</div>
</header>

What is a clean way to toggle a slide in menu?

Okay so I am working on my new personal website and I have came to making the off canvas menu toggable. How cna I do so?
So far I have:
var mainNav = document.getElementById('menu');
var navToggle = document.getElementById('menu-toggle');
mainNav.classList.add('collapsed');
function mainNavToggle() {
mainNav.classList.toggle('collapsed');
}
navToggle.addEventListener('click', mainNavToggle);
.collapsed {
margin-left: -330px;
}
.navigation {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 300px;
height: 100%;
color: #212121;
background-color: #FFFFFF;
transition: all ease-in-out 200ms;
box-shadow: 3px 0px 30px rgba(0, 0, 0, 0.4);
}
.navigation ul {
display: flex;
flex-direction: column;
padding: 90px 0 0 30px;
}
.navigation li {
margin-bottom: 30px;
}
.navigation a {
display: inline-block;
font-size: 16px;
font-weight: 500;
}
.navigation i {
vertical-align: top;
margin-right: 10px;
}
.navigation .double-line {
display: inline-block;
line-height: 1.45;
}
.navigation .double-line span {
display: block;
font-size: 12px;
opacity: 0.3;
}
.clicked span {
background-color: #000;
}
.menu-toggle {
background-color: transparent;
border: 0px;
outline: 0px;
cursor: pointer;
position: relative;
z-index: 10;
}
.menu-toggle span {
display: block;
width: 18px;
height: 2px;
margin: 4px;
background-color: #FFFFFF;
}
<button class="menu-toggle" id="menu-toggle">
<span></span>
<span></span>
<span></span>
</button>
<nav class="navigation" role="navigation" id="menu">
<ul>
/* Menu contents */
</ul>
</nav>
But with this code when the page loads you can see the menu being swept to the left, I dont want this.
How can I make my toggle button change colour when the menu is open?
Adding the class collapsed to the nav and removing the initial toggle solves your blinking issue! And toggling an active class on the toggle gets you a grey toggle when the $menu is open! The transition CSS property is optional to make the bg transition from transparent to grey look smooth.
Fiddle: https://jsfiddle.net/mbs1kymv/1/
JS:
var $menu = document.getElementById('menu');
var $toggle = document.getElementById('menu-toggle');
$toggle.addEventListener('click', function()
{
$menu.classList.toggle('collapsed');
$toggle.classList.toggle('active');
});
HTML:
<nav class="navigation collapsed" role="navigation" id="menu"> ... </nav>
CSS:
.menu-toggle {
transition: background-color 0.25s;
}
.menu-toggle.active {
background-color: #CCC;
}

show and hide menu with jquery

I would like,when clicking on the menu icon change to an X shape with animation and when clicking on X shape it change to menu icon.
I write this part.I have problem with clicking function. at first when I click on the menu button it change to X shape and show the menu but when I want to close menu my js codes does not work and I don't know why this happening.
I used bootstrap in my codes
I upload my site here
html
<div class="col-xs-6">
<a class="bazar" href="">دانلود اپلیکیشن </a>
<button type="button" style="z-index:401" class="navbar-toggle try-op" >
<span style="z-index:401" class="icon-bar top-m"></span>
<span style="z-index:401" class="icon-bar mid-m"></span>
<span style="z-index:401" class="icon-bar bottom-m"></span>
</button>
<div class="menu"> <!-- <span class="btnClose">×</span> -->
<ul>
<li>صفحه اصلی</li>
<li>سوالات متداول</li>
<li>فرصت های شغلی</li>
<li>درباره ما</li>
</ul>
</div>
</div>
js
$('.try-op').click(function() {
$('.navbar-toggle').removeClass('try-op');
$('.navbar-toggle').addClass('texting');
$('.top-m').addClass('top-animate');
$('.mid-m').addClass('mid-animate');
$('.bottom-m').addClass('bottom-animate');
$('.menu').addClass('opened');
var height = $( window ).height();
$('.menu').css('height',height);
});
$('.texting').click(function() {
$('.navbar-toggle').removeClass('texting');
$('.menu').removeClass('opened');
$('.top-m').removeClass('top-animate');
$('.mid-m').removeClass('mid-animate');
$('.bottom-m').removeClass('bottom-animate');
$('.navbar-toggle').addClass('try-op');
});
css
.icon-bar{
transition: 0.6s ease;
transition-timing-function: cubic-bezier(.75, 0, .29, 1.01);
}
.top-animate {
background: #fff !important;
top: 13px !important;
-webkit-transform: rotate(43deg);
transform: rotate(43deg);
transform-origin: 7% 100%;
-webkit-transform-origin: 7% 100%;
}
.mid-animate {
opacity: 0;
}
.bottom-animate {
background: #fff !important;
top: 13px !important;
-webkit-transform: rotate(-221deg);
transform: rotate(-221deg);
transform-origin: 45% 18%;
-webkit-transform-origin: 45% 18%;
margin-top: 0px !important;
}
.bazar-green, .bazar {
color: #fff;
display: block;
font-size: 20px;
position: absolute;
right: 80px;
top: 5px;
line-height: 43px;
background: url(image/bazarlogo.png) no-repeat left center;
padding-left: 80px;
z-index: 401;
}
.navbar-toggle {
display: block;
position: absolute;
right: 0px;
top: 0px;
}
.navbar-toggle{
float: right;
padding: 9px 10px;
margin-top: 8px;
margin-right: 15px;
margin-bottom: 8px;
background-color: transparent;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
.navbar-toggle .icon-bar {
background-color: #fff;
}
.navbar-toggle .icon-bar {
display: block;
width: 22px;
height: 2px;
border-radius: 1px;
}
.menu {
width: 300px;
position: absolute;
z-index: 400;
background: rgba(0,0,0,0.7);
padding: 10px 30px;
text-align: right;
color: #fff;
font-size: 17px;
transition: all 1s;
right: -316px;
}
.btnClose {
color: #fff;
font-size: 30px;
cursor: pointer;
z-index: 500;
}
You are effectively adding 2 click handlers to the same element. When you click on the span elements the second handler is executed, and as the click event propagates then the first click handler is executed.
You should change the logic. Instead of using addClass/removeClass and having 2 handlers you can use just 1 click handler and toggle the classNames using toggleClass method.
$('.try-op').click(function() {
var isOpened = $('.menu').toggleClass('opened').hasClass('opened');
if ( isOpened ) {
// the menu is opened
} else {
// ...
}
});
Another option that you have is using the event delegation technique. I see that you are removing the className in your first handler, probably in order to unbind the handler for the next click handling, but event handlers are bound to elements not to their classNames.
$(document).on('click', '.navbar-toggle.open', function() {
$(this).removeClass('open').addClass('close');
// ...
});
$(document).on('click', '.navbar-toggle.close', function() {
$(this).removeClass('close').addClass('open');
// ...
});
Use $('.navbar-toggle').click(function() {
instead of $('.navbar-toggle span').click(function() {

JavaScript onmouseout not closing properly

I'm trying to mouse over to bring down a menu. The javascript I have works somewhat right. When I mouse over the link or the menu, the menu stays displayed. However, when I mouse out i encounter the problem. My menu div disappears as it should, but the links stay for longer a second longer than the should.
Here is my javascript:
var timeout = 500;
var closetimer = null;
var menu = null;
function showTeams() {
cancelClose(); // keep showing menu
if (menu)
menu = menu.style.visiblity = 'hidden';
menu = document.getElementById('teams');
menu.style.visibility = 'visible';
}
function close() {
if (menu) {
menu.style.visibility = 'hidden';
}
}
function closeTeams() {
closetimer = window.setTimeout(close, timeout);
}
function cancelClose() {
if (closetimer) {
window.clearTimeout(closetimer);
closetimer = null;
}
}
My CSS:
#links {
width: 533px;
height: 40px;
position: absolute;
top: 105px;
left: 439px;
text-align: justify;
}
#links li {
display: inline;
}
#links ul {
display: inline;
}
#links span {
display: inline-block;
width: 100%;
}
#links a {
display: inline-block;
color: white;
text-decoration: none;
/* alternate browser support */
-o-transition:.5s;
-ms-transition:.5s;
-moz-transition:.5s;
-webkit-transition:.5s;
/* normal statement */
transition:.5s;
}
#links a:hover {
display: inline-block;
color: #70fc80;
text-decoration: none;
text-shadow: 0px 1px #707070;
}
#teams {
visibility: hidden;
position: absolute;
margin-left: 345px;
top: 31px;
border: #5260e5 3px solid;
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
background-color: #b4bcfb;
padding: 2px;
}
#teams a{
font-size: x-large;
position: relative;
color: #5260e5;
display: block;
margin: 0 auto;
width: 100px;
text-align: center;
text-decoration: none
}
#teams a:hover {
color: white;
text-shadow: 0 0 #000;
background-color: #5260e5;
display: block;
}
and my HTML:
<div id="links">
<ul>
<li>Home</li>
<li>Schedule</li>
<li>Standings</li>
<li>
Teams
<div id="teams" onmouseover="showTeams()" onmouseout="closeTeams()">
Team 1
Team 2
Team 3
Team 5
Team 6
Team 7
</div>
</li>
<li>Contact</li>
</ul>
<span></span>
</div>
Any ideas as to why the links are sticking around after the div closes?
You have transitions on your links:
-o-transition:.5s;
-ms-transition:.5s;
-moz-transition:.5s;
-webkit-transition:.5s;
/* normal statement */
transition:.5s;
This means that there will be a delay in changes. What do you want the transitions for?
See this fiddle with the transitions removed. You will need to scroll across to teams.
I think you just want to keep the transitions for when you hover. See this fiddle. In that case, move the transitions to hover:
#links a:hover {
-o-transition:.5s;
-ms-transition:.5s;
-moz-transition:.5s;
-webkit-transition:.5s;
/* normal statement*/
transition:.5s;
}

Categories

Resources