I made a dropdown that I took from templates on the internet. Here's what I've comed up with but is having a trouble. The problem is, everytime I'm clicking on each link on the dropdown, the dropdown closes. Here's the code:
jQuery(document).ready(function($){
//open/close mega-navigation
$('.cd-dropdown-trigger').on('click', function(event){
event.preventDefault();
toggleNav();
});
//close meganavigation
$('.cd-dropdown .cd-close').on('click', function(event){
event.preventDefault();
toggleNav();
});
//on mobile - open submenu
$('.has-children').children('a').on('click', function(event){
//prevent default clicking on direct children of .has-children
event.preventDefault();
var selected = $(this);
selected.next('ul').removeClass('is-hidden').end().parent('.has-children').parent('ul').addClass('move-out');
});
//on desktop - differentiate between a user trying to hover over a dropdown item vs trying to navigate into a submenu's contents
var submenuDirection = ( !$('.cd-dropdown-wrapper').hasClass('open-to-left') ) ? 'right' : 'left';
$('.cd-dropdown-content').menuAim({
activate: function(row) {
$(row).children().addClass('is-active').removeClass('fade-out');
if( $('.cd-dropdown-content .fade-in').length == 0 ) $(row).children('ul').addClass('fade-in');
},
deactivate: function(row) {
$(row).children().removeClass('is-active');
if( $('li.has-children:hover').length == 0 || $('li.has-children:hover').is($(row)) ) {
$('.cd-dropdown-content').find('.fade-in').removeClass('fade-in');
$(row).children('ul').addClass('fade-out')
}
},
exitMenu: function() {
$('.cd-dropdown-content').find('.is-active').removeClass('is-active');
return true;
},
submenuDirection: submenuDirection,
});
//submenu items - go back link
$('.go-back').on('click', function(){
var selected = $(this),
visibleNav = $(this).parent('ul').parent('.has-children').parent('ul');
selected.parent('ul').addClass('is-hidden').parent('.has-children').parent('ul').removeClass('move-out');
});
function toggleNav(){
var navIsVisible = ( !$('.cd-dropdown').hasClass('dropdown-is-active') ) ? true : false;
$('.cd-dropdown').toggleClass('dropdown-is-active', navIsVisible);
$('.cd-dropdown-trigger').toggleClass('dropdown-is-active', navIsVisible);
if( !navIsVisible ) {
$('.cd-dropdown').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){
$('.has-children ul').addClass('is-hidden');
$('.move-out').removeClass('move-out');
$('.is-active').removeClass('is-active');
});
}
}
//IE9 placeholder fallback
//credits http://www.hagenburger.net/BLOG/HTML5-Input-Placeholder-Fix-With-jQuery.html
if(!Modernizr.input.placeholder){
$('[placeholder]').focus(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
}).blur(function() {
var input = $(this);
if (input.val() == '' || input.val() == input.attr('placeholder')) {
input.val(input.attr('placeholder'));
}
}).blur();
$('[placeholder]').parents('form').submit(function() {
$(this).find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
});
}
});
HTML Code
<div class="cd-dropdown-wrapper nav-div cd-dropdown-trigger" href="#0" id="nav-icon2">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<nav class="cd-dropdown">
<h2>Title</h2>
Close
<ul class="cd-dropdown-content">
<li class="has-children">Catalog
<ul class="cd-secondary-dropdown is-hidden">
<li class="go-back">Menu</li>
<li class="see-all">All Products</li>
<li class="has-children">Travel Gear
<ul class="is-hidden">
<li class="go-back">Clothing</li>
<li class="has-children">Soft Shell
<ul class="is-hidden">
<li class="go-back"></li>
<li>Soft Shell Gen1</li>
<li>Soft Shell Joey</li>
<li class="see-all">All Soft Shell Jackets</li>
</ul>
</li>
<li class="has-children">Sweatshirts
<ul class="is-hidden">
<li class="go-back"></li>
<li class="see-all">All Sweatshirt Jackets</li>
<li>Sweatshirts Gen1</li>
<li>Sweatshirt Joey</li>
</ul>
</li>
<li class="has-children">Polar Fleece
<ul class="is-hidden">
<li class="go-back"></li>
<li class="see-all">All Polar Fleece</li>
<li>Polar Fleece Gen1</li>
<li>Joey Polar Fleece</li>
</ul>
</li>
<li>Windbreakers</li>
<li>Travel Pillow</li>
</ul>
</li>
</ul>
<!-- .cd-secondary-dropdown -->
</li>
<li>About Us</li>
<li>FAQ</li>
<li>Make Money Selling our Jackets</li>
</ul>
<!-- .cd-dropdown-content -->
</nav>
<!-- .cd-dropdown -->
</div>
<script>
$(document).ready(function(){
$('#nav-icon2').click(function(){
$(this).toggleClass('open');
});
});
$("document").ready(function() {
$('#nav-icon2').on('click', function(e) {
if($(this).hasClass('open')) {
e.stopPropagation();
}
});
});
</script>
if you have a open and close button, you should do a hide show. not a toggle.
for instance have a button that adds a style or adds a class with the CSS display:none;
<div style="display:none;">Hidden Stuff</div>
then have a button that gives it the CSS property display:block;
<div style="display:block;">Shown Stuff</div>
but more importantly, its not included in the snippit but i thought i'd ask, do you include jQuery in the <head> tag of your index.html?
Related
I have an issue of getting the first click per link clicked, I have tried with one click event .one() but since I'm preventing the default it cause a redirection. I want to get add something if item clicked is equal to 1 and remove if clicked more than one time per a link.
// $('.menu>li>a').one('click', function(e){});
let clickCount = 0;
$('.menu>li>a').on('click', function(e) {
clickCount++;
let $this = $(this);
if (clickCount == 1) {
//show loader
$('.loader').show();
setTimeout(function() {
$('.loader').hide();
}, 5000);
$this.next('.dropdown').addClass('active');
} else {
$this.next('.dropdown').addClass('active');
}
e.preventDefault()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li>item1
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
<li>item2
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
<li>item3
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
</ul>
Try using jQuery's data storage to know if a link has been clicked before. This would allow you to track each link individually:
// $('.menu>li>a').one('click', function(e){});
$('.menu>li>a').on('click', function(e) {
let $this = $(this);
const firstClick = !$this.data('clickedBefore');
if (firstClick) {
$this.data('clickedBefore', true)
//show loader
$('.loader').show();
setTimeout(function() {
$('.loader').hide();
}, 5000);
$this.next('.dropdown').addClass('active');
} else {
$this.next('.dropdown').addClass('active');
}
e.preventDefault()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li>item1
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
<li>item2
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
<li>item3
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
</ul>
Update:
is there another alternative without using data('clickedBefore', true) and adding class to link to achieve the same result?
Yes. Generally speaking, if all you need is just some control properties, using data is cleaner than adding classes. But if you intend to style the element or if your project already uses classes for control elsewhere (so keeping consistency would matter), it could make sense to use them instead:
// $('.menu>li>a').one('click', function(e){});
$('.menu>li>a').on('click', function(e) {
let $this = $(this);
const firstClick = !$this.hasClass('clicked-before');
if (firstClick) {
$this.addClass('clicked-before');
//show loader
$('.loader').show();
setTimeout(function() {
$('.loader').hide();
}, 5000);
$this.next('.dropdown').addClass('active');
} else {
$this.next('.dropdown').addClass('active');
}
e.preventDefault()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li>item1
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
<li>item2
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
<li>item3
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
</ul>
You can just add two event listeners for both use cases. One for you to disable the default behavior and one for the click you would like to capture.
let clickCount = 0;
$('.menu > li > a').on('click', function(e) {
console.log('checking click for things');
clickCount++;
let $this = $(this);
if (clickCount === 1) {
console.log('Only the first click will show the loader');
$('.loader').show();
setTimeout(function() {
$('.loader').hide();
}, 5000);
$this.next('.dropdown').addClass('active');
} else {
$this.next('.dropdown').addClass('active');
}
});
$('.menu > li > a').on('click', function(e) {
e.preventDefault();
console.log('All clicks will prevent default');
});
.loader {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li>item1
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
<li>item2
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
<li>item3
<ul class="dropdown">
<li>content1</li>
</ul>
</li>
</ul>
<div class="loader">Loader</div>
i want to convert from hover to mouse click, here's some of the code
HTML
<li class="has-dropdown">
Click Me
<ul class="dropdown">
<li>Web Design</li>
<li>eCommerce</li>
<li>Linux</li>
<li>API</li>
</ul>
</li>
and here's the script but still in mouseover/mouseleave
var dropdown = function() {
$('.has-dropdown').mouseenter(function(){
var $this = $(this);
$this
.find('.dropdown')
.css('display', 'block')
.addClass('animated-fast fadeInUpMenu');
}).mouseleave(function(){
var $this = $(this);
$this
.find('.dropdown')
.css('display', 'none')
.removeClass('animated-fast fadeInUpMenu');
});
};
dropdown()
How can I change this from hover to click?
You could use .click with .toggleClass
$('#toggle').click(function() {
$('.has-dropdown')
.find('.dropdown')
.css({
display: function(_, value) {
return value === 'none' ? 'block' : 'none'
}
})
.toggleClass('animated-fast fadeInUpMenu')
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="has-dropdown">
<a id="toggle" href="#">Click Me</a>
<ul class="dropdown">
<li>Web Design</li>
<li>eCommerce</li>
<li>Linux</li>
<li>API</li>
</ul>
</li>
You can use the onclick="YourFunction()" and it will execute the function only when you click it.
Not sure if this is what you want, but see this example
HTML
<input type="button" value="Click me" onclick="showlist()" />
<div id="list" style="display:none;" >
<ul class="dropdown" type="hidden">
<li>Web Design</li>
<li>eCommerce</li>
<li>Linux</li>
<li>API</li>
</ul>
</div>
JS
function showlist() {
var x = document.getElementById("list");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
http://jsfiddle.net/5an2mo0g/4/
I have following code and when I hover on Menu it has some dropdown submenus and I am not able to click on any of my submenu links:
HTML:
<li class="onesource-user">
<%=expert.firstname %> <%=expert.lastname %>(<%= expert.login %><%=session.getAttribute("multi_lobs")==null?"":" - "+view_name %>)
<ul>
<li>Profile</li>
<li>Favorites</li>
<li class="log-out">Log out</li>
</ul>
JS:
$('.onesource-user').on('click', function(e){
e.preventDefault();
$(this).toggleClass('open');
return false;
})
Screenshot:
screenshot
Because of you're using event on .onesource-user so it'll aply on all it children so ( e.preventDefault + return false ) .
this would help .
$('.onesource-user > a').on('click', function(e){
e.preventDefault();
$(this).parent().toggleClass('open');
return false;
})
see the above snippet :
$('.onesource-user > a').on('click', function(e){
e.preventDefault();
$(this).parent().toggleClass('open');
return false;
})
.onesource-user ul{
display:none;
}
.onesource-user.open ul{
display:block
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<li class="onesource-user">
Sample UserName
<ul>
<li>Profile</li>
<li>Favorites</li>
<li class="log-out">Log out</li>
</ul>
</li>
Live Link : http://velnikolic.com/elliotDev5/
contentActive = true;
var selector = '.mainNav li';
$(selector).on('click', function(){
$(selector).removeClass('active');
$(this).addClass('active');
});
$(".filter").click(function() {
category = $(this).data("filter");
if ($(this).hasClass("active")) {
$(this).removeClass('active');
}
pLoaded();
if (contentActive == true && status == "false") {
$('.contentWrap').children().fadeOut('slow').promise().done(function() {
$('#portfolio').mixItUp({
load: {
filter: category
}
});
contentActive = false;
});
} else {
$('#portfolio').mixItUp({
load: {
filter: category
}
});
}
});
$('.link a').click(function() {
var id = $(this).attr('href');
$('.contentWrap').children().fadeOut('slow').promise().done(function() {
pLoaded();
alert(status);
if(status == "true") {
$('#portfolio').fadeOut('slow').promise().done(function() {
$('#portfolio').mixItUp('destroy', true);
$('#portfolio').removeAttr('style');
$(id).fadeIn('slow', function () {
// Animation complete
});
});
} else {
$(id).fadeIn('slow', function () {
// Animation complete
});
}
contentActive = true;
});
});
var status;
status = false;
function pLoaded() {
status = $('#portfolio').mixItUp('isLoaded');
return status;
}
$(".nav li a").click(function(){
if ($( "#navMenu" ).hasClass( "canvas-slid" )) {
$('#navMenu').offcanvas('hide');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-3 col-sm-4 offcanvas-xs" id="navMenu">
<div class="sidebar-nav">
<div class="navbar navbar-default" role="navigation">
<ul class="nav navbar-nav mainNav">
<img id="logo" class="img-responsive hidden-xs" src="assets/img/logo2.jpg" />
<li class="link">
Home
</li>
<li class="link">
About
</li>
<li class="filter" data-filter=".category-1">
Animation
</li>
<li class="filter" data-filter=".category-2">
Commercial
</li>
<li class="filter" data-filter=".category-3">Documentary
</li>
<li class="filter" data-filter=".category-4">
Film
</li>
<li class="filter" data-filter=".category-5">
Music
</li>
<li class="filter" data-filter=".category-6">
Video Games
</li>
<li class="link">
Services
</li>
</ul>
</div>
</div>
</div>
<div class="contentWrap">
//content
</div>
<div id="portfolio">
</div>
Basically when you click a non filter link it check if theres the portfolio div and fade it out if there is, then load the content.
If a filter is clicked it should check if there is any other content fade it out if so and load the portfolio.
The problem seems to be with the if statements, different iterations work in firefox and chrome and different iterations work only in IE. Driving me crazy to figure out one that works for both
For whatever reason, mixitup2's callback .mixItUp('isLoaded'); returns as a string in IE 11 and a boolean in Chrome and Firefox. My solution could probably be more elegant, but this is what I'm using for not.
if ( (contentActive == true) && (status == "false" || status == false ))
I have a drop down menu with jquery and I want to modify some text in different way depending on what is selected in the drop down menu.
The drop down menu works.
Html code:
<div>
<ul class="myMenu">
<li>Choose your location
<ul>
<li id="op1">option1</li>
<li id="op2">option2</li>
<li id="op2">option3</li>
</ul>
</li>
</ul>
</div>
<div>
<h1 id="text_to_change">Welcome to blabla</h1>
</div>
Javascript code:
$(document).ready(function() {
$('.myMenu li ul li').click( function(event){
$(document).find('#text_to_change').css('visibility', 'visible');
$('.myMenu').hide();
if ($(this) == '#op1'){
$('#text_to_change').text("text changed");
}
if ($(this) == '#op2'){
$('#text_to_change').text("text changed differently");
}
else{
$('#text_to_change').text("text changed differently again");
}
});
});
Why does ($(this) == '#op1') not work?
You are trying to compare a jquery object $(this) with a string #op1
To get the id of the element use:
$(this).attr('id');
It will give you the id of the element without the #
Also i think your second if needs to be an else if { ...
$(document).ready(function() {
$('.myMenu li ul li').click( function(event){
console.log($(this).attr('id'), $(this).prop('id'));
$(document).find('#text_to_change').css('visibility', 'visible');
$('.myMenu').hide();
if ($(this).attr('id') == 'op1'){
$('#text_to_change').text("text changed");
}
else if ($(this).attr('id') == 'op2'){
$('#text_to_change').text("text changed differently");
}
else{
$('#text_to_change').text("text changed differently again");
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div>
<ul class="myMenu">
<li>Choose your location
<ul>
<li id="op1">option1</li>
<li id="op2">option2</li>
<li id="op2">option3</li>
</ul>
</li>
</ul>
</div>
<div>
<h1 id="text_to_change">Welcome to blabla</h1>
</div>
This two item must not share the same id 'op2'
<li id="op2">option2</li>
<li id="op2">option3</li>