I've built a jQuery dropdown menu as a fallback from the CSS3 version that's normally used. I'd like to have it delay the dropdown the same way as in the CSS, but I'm not sure how to do it.
Here's the script:
var iconWidth = 34; // default width of navigation <li>'s
var slideWidth = 200; // width of the longest slider
var slideTime = 500; // duration of the sliding animation
var dropHeight = 160; // height of tallest dropdown, should be number of <li>'s x 40
var dropTime = 500; // duration of the dropdown animation
$(function() {
// expanding
$("#nav li").not("#logo, .parent li").hover(
function(){
$(this).animate({width:slideWidth + "px"},{queue:false,duration:slideTime});
}, function(){
$(this).animate({width:iconWidth + "px"},{queue:false,duration:slideTime});
}
);
// dropdown
$("#nav li.parent").hover(
function(){
$(this).children("ul").animate({height:dropHeight + "px"},{queue:false,duration:dropTime});
}, function(){
$(this).children("ul").animate({height:"0px"},{queue:false,duration:dropTime});
}
);
});
What it currently does is expand both ways at the same time, but I would like it to expand first to the right, then down, then when contracting, first contract up, then left.
So like this:
Hover:
-->
|
v
Unhover:
^
|
<--
So basically, in steps, not at the same time. Can someone show me how to modify my script to make this work?
Also, how do I make it drop down based on the number of li's in the navigation, rather than a set height?
EDIT: Here's some example HTML:
<ul id="nav">
<li id="logo">
<p>
<img src="images/logo.png" />
</p>
</li>
<li>
<p>
<img src="images/dashboard.png" /> Go to Dashboard
</p>
</li>
<li class="parent">
<p>
<img src="images/nav-item.png" /> Nav-Item
</p>
<ul>
<li>
<p>
Create a page
</p>
</li>
<li>
<p>
View All Pages
</p>
</li>
</ul>
</li>
</ul>
I hope i understood your question correctly:
$(function() {
// expanding
$("#nav li").not("#logo, .parent li").hover(
function(){
$(this).animate({width:slideWidth + "px"},{duration:slideTime});
}, function(){
$(this).delay(slideTime).animate({width:iconWidth + "px"},{duration:slideTime});
}
);
// dropdown
$("#nav li.parent").hover(
function(){
$(this).children("ul").delay(slideTime).animate({height:dropHeight + "px"},{duration:dropTime});
}, function(){
$(this).children("ul").animate({height:"0px"},{duration:dropTime});
}
);
});
Related
I bought this theme a while back and have been chopping it up and modifying it to add/remove functionality. There is this slidein menu that appears on the page once a link is clicked from the navbar menu. The issue is that there is an X button to close the menu that is supposed to toggle/remove a class from the #btn-offcanvas-menu element when it is clicked (#btn-close-canvasmenu is clickable element); it works on the desktop but not the responsive mobile site. The only way it is toggled/removed on mobile is if the original link is clicked again. I have looked at the below questions here, and several others, including trying to use the closest/find options but nothing seems to work. What am I missing?
Desired behavior: the isLeft class should toggle/be removed when the #btn-close-canvasmenu link is clicked. It is on desktop but not mobile.
Javascript not working on mobile but works on desktop.
JavaScript - removeClass not working?
ToggleClass and RemoveClass not working
JQuery - ToggleClass/AddClass/RemoveClass
How to toggle class of closest element jquery toggle class on closest span
This is relevant portion of the index page...
<li id="recent-mobile"><!-- this is hidden by CSS on desktop -->
<a id="btn-offcanvas-menu" href="#">Recent Results</a>
</li>
<li id="recent-results"><!-- this is hidden by CSS on mobile -->
<div class="header-buttons pull-right hidden-xs hidden-sm">
<div class="navright-button">
<i class="fa fa-bars"> Recent Results</i>
</div>
</div>
</li>
<!-- Menu OffCanvas right begin -->
<div class="navright-button">
<div class="compact-menu-canvas" id="offcanvas-menu">
<h3>menu</h3><a id="btn-close-canvasmenu"><i class="fa fa-close"></i></a>
<nav>
<ul class="clearfix">
<li>Home</li>
<li>Features</li>
<li>Pages</li>
<li>Portfolios</li>
<li>Shop</li>
<li>Blog</li>
<li>Contact Us</li>
</ul>
</nav>
</div>
</div>
<!-- Menu OffCanvas right close -->
This is the relevant portion of the javascript compact.js file...
$("#btn-close-canvasmenu").on("click", function() {
$("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300), $("a#btn-offcanvas-menu").removeClass("isLeft")
});
$(document).on("click", "#btn-offcanvas-menu, #btn-offcanvas-menu-mobile", {} , function(a){
var id = $(this).attr('id');
if (id === "btn-offcanvas-menu-mobile") {
$("#btn-close-canvasmenu").toggleClass("mobile");
}
return a.preventDefault(), $(this).hasClass("isLeft") ? $("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300) : $("#offcanvas-menu").stop().animate({
right: "0px"
}, 300), $(this).toggleClass("isLeft"), false
});
EDIT (fixed 2/16/20): I edited the js file file to reflect this updated function: $("#btn-close-canvasmenu").on("click", function()
Essentially, what fixed it was changing the selector from #btn-offcanvas-menu to a#btn-offcanvas-menu. Not sure why that worked as opposed to using closest/find method but once I did, it toggled/removed the class on both desktop and mobile correctly. If anyone has anything thoughts on why the a made the difference with the selector, I'd appreciate the feedback as I am not an expert on js/jQuery. Otherwise, this can be considered closed.
Changing the selector in the compact.js file from #btn-offcanvas-menu to a#btn-offcanvas-menu fixed the issue and while this worked, it was the wrong way to correct the issue as connexo pointed out due to the duplicate ids.
The correct way to resolve this was to change the mobile navbar itself so I could use an id specifically for the mobile that only appeared there.
<nav id="mobile-menu" class="site-mobile-menu hidden-lg hidden-md">
<ul>
<li id="recent-mobile">
Recent Results
</li>
</ul>
</nav>
Next I changed the js function that populated the html for the mobile menu to use prepend instead of append so it populated everything above the Recent Results link...
$("#desktop-menu > ul").children().clone().prependTo($("#mobile-menu > ul")), $("#show-mobile-menu").on("click", function() {
$(this).toggleClass("clicked"), $("#mobile-menu > ul").stop(true, true).slideToggle()
});
Then I tweaked the js function to toggle the class to mobile for the #btn-close-canvasmenu if the selector was #btn-offcanvas-menu-mobile to be used later...
$(document).on("click","#btn-offcanvas-menu,#btn-offcanvas-menu-mobile", {} , function(a){
var id = $(this).attr('id');
if (id === "btn-offcanvas-menu-mobile") {
$("#btn-close-canvasmenu").toggleClass("mobile");
}
return a.preventDefault(), $(this).hasClass("isLeft") ? $("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300) : $("#offcanvas-menu").stop().animate({
right: "0px"
}, 300), $(this).toggleClass("isLeft"), false
});
Finally, I tweaked the js function that closed the menu to check the class to determine which id to toggle the isLeft class for...
$(document).on("click","#btn-close-canvasmenu", {} , function(a){
var id = $(this).attr('id');
if ($(this).hasClass("mobile")) {
var container = $("#btn-offcanvas-menu-mobile");
$("#btn-close-canvasmenu").toggleClass("mobile");
} else {
var container = $("#btn-offcanvas-menu");
}
$("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300), container.removeClass("isLeft")
});
I write a filter product by category.
When I click a category, it will add a class selected to element and the background of this category had selected.
I think problem at line:
if (!$filterLinks.hasClass('selected') )
I want to when user click another element, all element should go to background default is white.
My HTML structure:
<ul id="filters">
<li> <a class="selected" data-filter="*"></a> All <li>
<li> <a data-filter=".nokia"></a> Nokia <li>
<li> <a data-filter=".samsung"></a> Samsung <li>
</ul>
And my code:
var $filterLinks = $('#filters a');
$filterLinks.click(function(){
var $this = $(this);
$this.parents('li').css("background", "red");
if ( $this.hasClass('selected') ) {
return;
}
$filterLinks.filter('.selected').removeClass('selected');
$this.addClass('selected');
// problem at here, I want when user click another <li> element,
// all <li> element should be go to background default is `white`.
if (!$filterLinks.hasClass('selected') ) {
$filterLinks.parents('li').css("background", "white");
}
}
Full code at here: https://jsfiddle.net/az2e51c7/
Here you use my code:
$("#filters li").click(function()
{
$("#filters li").removeClass("selected");
$(this).addClass("selected");
});
If you want to use CSS
try
li > a:not(.selected) {
//add your css here
}
I have a drop down menu where the user selects a location and it scrolls to the div to reveal the address (10 different locations).
This works well in a desktop browser. However on the ipad, iphone and nexus it doesnt work because of touch screen.
This is my code:-
<html>
<div class="location">
<ul>
<li>Select an Office
<ul class="officeselect">
<li><a data-emailaddress="" data-address='<span class="address">99 Walnut Tree Close</span>
<span class="address">Guildford</span>
<span class="address">Surrey</span>
<span class="address">GU1 4UQ</span><br>
<span class="address">T: +44 1483 881500</span>
<span class="address">info#petroplan.com</span>' href="">UK Head</a>
</li>
</ul>
</li>
</ul>
</div>
<div class="span4 alpha">
<div class="addresstitle">
<h3>Address</h3>
</div>
<div class="address">
</div>
</div>
</html>
<script>
// Scroll down to map and address function
$(".location ul li ul a").click(updateAddressDisplay);
function updateAddressDisplay(src) {
$('.office-sel-cont .chooser').text($(this).text());
var target = $(".address");
var source;
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
if (src === null)
source = $(".black-sectors li a.adr-src:eq(0)");
else
source = $(this);
target.fadeOut();
target.html(source.data("address") + source.data("emailaddress"));
target.fadeIn();
var chooser = $(this).parent().parent().parent().find('.chooser');
if (chooser.hasClass('open')) {
chooser.removeClass('open');
chooser.next($('.black-sectors')).animate({
'top': '60px',
'opacity': 0
}, 600, 'easeOutQuint', function() {
chooser.next($('.black-sectors')).toggle();
});
return false;
} else {
}
return false;
}
</script>
And I used this below from this website, but it's still dodgy.
<script>
$('.location ul li ul a').on('click touchend', function(e) {
e.preventDefault();
var el = $(this);
var link = el.attr('href');
window.location = link;
});
</script>
Thanks for your help.
this is the fiddle:-http://jsfiddle.net/ScVs9/
For your drop down list to work on a touch screen device you need to trigger the drop-down using a javascript click event rather than the css hover. Simple way would be create a class, called something like .active and then use a function like this:
$('.location a').on('click', function(){
$('.officeselect').toggleClass('active')
});
The active class would simply have visibility set to visible:
ul.officeselect.active {visibility:visible;}
The user should then be able to select the correct link and display the address as per usual.
I hope this helps
I have this navigation that can expand when the user clicks a drop down arrow, This navigations is held within a box container with overflow hidden. What I'm trying to achieve is when the users mouse is in the top 20% of the box it scrolls up, and when its in the bottom 20% it scrolls down. I've tried a various number of plugins and tried coding it myself but so far no luck!
This has to be responsive so I am working in percentages.
HTML SET UP:
<div class="container">
<div class="title">Where to next? <span>(this title will be fixed)</span></div>
<ul class="pagesNav">
<li>Page1</li>
<li class="has_children">
Page2
<ul class="children">
<li>Child1</li>
<li>Child2</li>
<li>Child3</li>
</ul>
</li>
<li>Page3</li>
<li>Page4</li>
<li>Page5</li>
<li>Page6</li>
</ul>
</div>
Take a look at my fiddle:
http://jsfiddle.net/7d8fA/
You can get the desired effect by this :
var height=$('.container').height();
var top20=(height/100)*20;
var top80=height-top20;
$('.container').mouseover(function(e) {
e.stopPropagation();
if ((e.clientY-e.currentTarget.offsetTop)<top20) {
$(".container").animate({
scrollTop: 0
}, 10);
} else if (e.clientY>top80) {
$(".container").animate({
scrollTop: height
}, 10);
}
});
forked fiddle -> http://jsfiddle.net/U5Uk8/
I am trying to create a simple tab bar for a site that has the ability to scroll for tabs that do not fit on the page. This is quite simple and does not need to have any ajax or dynamically loaded content...it simply displays all the tabs, and when you click one, it takes you to another page.
I have scoured the internet and can not seem to find anything other than:
http://www.extjs.com/deploy/dev/examples/tabs/tabs-adv.html
however this is very heavy and complicated...I am looking for a lightweight example in jquery. If anyone can help I would be grateful!
I ended up writing it myself with a div who's overflow is set to hidden. Then used the jquery below to move the tabs in the div.
$(document).ready(function()
{
$('.scrollButtons .left').click(function()
{
var content = $(".tabs .scrollable .content")
var pos = content.position().left + 250;
if (pos >= 0)
{
pos = 0;
}
content.animate({ left: pos }, 1000);
});
$('.scrollButtons .right').click(function()
{
var content = $(".tabs .scrollable .content")
var width = content.children('ul').width();
var pos = content.position().left - 250;
//var width = content.width();
if (pos <= (width * -1) + 670)
{
pos = (width * -1) + 600;
}
content.animate({ left: pos }, 1000);
});
});
My Html looked like this:
<div class="tabs">
<div class="scrollable">
<div class="content">
<ul>
<li>Tab1</li>
<li>Tab2</li>
<li>Tab3</li>
<li>Tab4</li>
<li>Tab5</li>
</ul>
</div>
</div>
<div class="scrollButtons">
<ul>
<li>
<div class="left">
</div>
</li>
<li>
<div class="right">
</div>
</li>
</ul>
</div>
</div>
I have just created a plugin myself:
Project home: http://jquery.aamirafridi.com/jst
Could you simply wrap the tabs in a DIV with overflow-x: auto set in the CSS?
I always use JQuery UI tabs as a starting point for tabs. You can customize the JQuery UI download in the download section of the website. This method should be lighter than any other implementation, if you are already using JQuery on your website.
Out of the box, the JQuery UI tabs will not give you the scrolling you desire. This I believe could be achieved by altering the CSS, but more than likely will be easier if you alter the navigation of your site (i.e. create more levels, use shorter titles).
Hope this helps