I am creating a drop down menu that shows a submenu when clicked instead of using hover.
When I click it is displayed as it should be but I would like that when I click on another option the previous one is hidden and not kept open as right now.
In advance, thank you very much to the person who takes the trouble to help me, here is the code I'm working with.
$('.parent a').on("click", function(e) {
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
* {
margin: 0;
padding: 0;
outline: 0;
box-sizing: border-box;
}
.parent {
display: block;
position: relative;
float: left;
line-height: 30px;
background-color: #4FA0D8;
border-right: #CCC 1px solid;
}
.parent a {
margin: 10px;
color: #FFFFFF;
text-decoration: none;
}
.parent>ul {
position: absolute;
}
.child {
display: none;
}
.child li {
background-color: #E4EFF7;
line-height: 30px;
border-bottom: #CCC 1px solid;
border-right: #CCC 1px solid;
width: 100%;
}
.child li a {
color: #000000;
}
ul {
list-style: none;
margin: 0;
padding: 0px;
min-width: 10em;
}
ul ul ul {
left: 100%;
top: 0;
margin-left: 1px;
}
li:hover {
background-color: #95B4CA;
}
.parent li:hover {
background-color: #F0F0F0;
}
.expand {
font-size: 12px;
float: right;
margin-right: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li class="parent">Popular Toys
<ul class="child">
<li class="parent">Video Games <span class="expand">»</span>
<ul class="child">
<li>Car</li>
<li>Bike Race</li>
<li>Fishing</li>
</ul>
</li>
<li>Barbies</li>
<li>Teddy Bear</li>
<li>Golf Set</li>
</ul>
</li>
<li class="parent">Recent Toys
<ul class="child">
<li>Yoyo</li>
<li>Doctor Kit</li>
<li class="parent">Fun Puzzle<span class="expand">»</span>
<ul class="child">
<li><a href="#" nowrap>Cards</a></li>
<li><a href="#" nowrap>Numbers</a></li>
</ul>
</li>
<li>Uno Cards</li>
</ul>
</li>
<li class="parent">Toys Category
<ul class="child">
<li>Battery Toys</li>
<li class="parent">Remote Toys <span class="expand">»</span>
<ul class="child">
<li>Cars</li>
<li>Aeroplane</li>
<li>Helicopter</li>
</ul>
</li>
<li>Soft Toys
</li>
<li>Magnet Toys</li>
</ul>
</li>
</ul>
Move the display logic to ".active" selector in css,
.active {
display: block;
}
then try the following script.
It would check if the click is not inside current menu, if the click is anywhere but current menu, active class will be removed.
var menu = $('.parent a').next('ul')
$(document).mouseup(e => {
if (!menu.is(e.target) // if the target of the click isn't the container...
&& menu.has(e.target).length === 0) // ... nor a descendant of the container
{
menu.removeClass("active");
}
});
$('.parent a').on("click", function (e) {
$(this).next('ul').toggleClass("active");
e.stopPropagation();
e.preventDefault();
});
Here's the full code,
var menu = $('.parent a').next('ul')
$(document).mouseup(e => {
if (!menu.is(e.target) // if the target of the click isn't the container...
&& menu.has(e.target).length === 0) // ... nor a descendant of the container
{
menu.removeClass("active");
}
});
$('.parent a').on("click", function (e) {
$(this).next('ul').toggleClass("active");
e.stopPropagation();
e.preventDefault();
});
* {
margin: 0;
padding: 0;
outline: 0;
box-sizing: border-box;
}
.parent {
display: block;
position: relative;
float: left;
line-height: 30px;
background-color: #4FA0D8;
border-right: #CCC 1px solid;
}
.parent a {
margin: 10px;
color: #FFFFFF;
text-decoration: none;
}
.parent>ul {
position: absolute;
}
.child {
display: none;
}
.active {
display: block;
}
.child li {
background-color: #E4EFF7;
line-height: 30px;
border-bottom: #CCC 1px solid;
border-right: #CCC 1px solid;
width: 100%;
}
.child li a {
color: #000000;
}
ul {
list-style: none;
margin: 0;
padding: 0px;
min-width: 10em;
}
ul ul ul {
left: 100%;
top: 0;
margin-left: 1px;
}
li:hover {
background-color: #95B4CA;
}
.parent li:hover {
background-color: #F0F0F0;
}
.expand {
font-size: 12px;
float: right;
margin-right: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li class="parent">Popular Toys
<ul class="child">
<li class="parent">Video Games <span class="expand">»</span>
<ul class="child">
<li>Car</li>
<li>Bike Race</li>
<li>Fishing</li>
</ul>
</li>
<li>Barbies</li>
<li>Teddy Bear</li>
<li>Golf Set</li>
</ul>
</li>
<li class="parent">Recent Toys
<ul class="child">
<li>Yoyo</li>
<li>Doctor Kit</li>
<li class="parent">Fun Puzzle<span class="expand">»</span>
<ul class="child">
<li><a href="#" nowrap>Cards</a></li>
<li><a href="#" nowrap>Numbers</a></li>
</ul>
</li>
<li>Uno Cards</li>
</ul>
</li>
<li class="parent">Toys Category
<ul class="child">
<li>Battery Toys</li>
<li class="parent">Remote Toys <span class="expand">»</span>
<ul class="child">
<li>Cars</li>
<li>Aeroplane</li>
<li>Helicopter</li>
</ul>
</li>
<li>Soft Toys
</li>
<li>Magnet Toys</li>
</ul>
</li>
</ul>
using siblings(), you have quickest solution:
parents("li.parent").last() keeps the highest parent li.parent of selected item
.sibling() keeps all others li.parent brothers (of main menu)
.find("ul") keeps all ul children from all li.parent brothers
$('.parent a').on("click", function(e) {
$(this).parents("li.parent").last().siblings().find("ul").hide();
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
$('.parent a').on("click", function(e) {
$(this).parents("li.parent").last().siblings().find("ul").hide();
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
* {
margin: 0;
padding: 0;
outline: 0;
box-sizing: border-box;
}
.parent {
display: block;
position: relative;
float: left;
line-height: 30px;
background-color: #4FA0D8;
border-right: #CCC 1px solid;
}
.parent a {
margin: 10px;
color: #FFFFFF;
text-decoration: none;
}
.parent>ul {
position: absolute;
}
.child {
display: none;
}
.child li {
background-color: #E4EFF7;
line-height: 30px;
border-bottom: #CCC 1px solid;
border-right: #CCC 1px solid;
width: 100%;
}
.child li a {
color: #000000;
}
ul {
list-style: none;
margin: 0;
padding: 0px;
min-width: 10em;
}
ul ul ul {
left: 100%;
top: 0;
margin-left: 1px;
}
li:hover {
background-color: #95B4CA;
}
.parent li:hover {
background-color: #F0F0F0;
}
.expand {
font-size: 12px;
float: right;
margin-right: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li class="parent">Popular Toys
<ul class="child">
<li class="parent">Video Games <span class="expand">»</span>
<ul class="child">
<li>Car</li>
<li>Bike Race</li>
<li>Fishing</li>
</ul>
</li>
<li>Barbies</li>
<li>Teddy Bear</li>
<li>Golf Set</li>
</ul>
</li>
<li class="parent">Recent Toys
<ul class="child">
<li>Yoyo</li>
<li>Doctor Kit</li>
<li class="parent">Fun Puzzle<span class="expand">»</span>
<ul class="child">
<li><a href="#" nowrap>Cards</a></li>
<li><a href="#" nowrap>Numbers</a></li>
</ul>
</li>
<li>Uno Cards</li>
</ul>
</li>
<li class="parent">Toys Category
<ul class="child">
<li>Battery Toys</li>
<li class="parent">Remote Toys <span class="expand">»</span>
<ul class="child">
<li>Cars</li>
<li>Aeroplane</li>
<li>Helicopter</li>
</ul>
</li>
<li>Soft Toys
</li>
<li>Magnet Toys</li>
</ul>
</li>
</ul>
You could try with
$('.parent a').on("click", function (e) {
$('.parent ul').hide();
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
Related
I'm using the .toggle('slide'); from jquery to hide and show my submenu though I was wondering why the animation is difference. it slides from left to right and up to down instead of having a fixed height and sliding from the left to right.
HTML:
<div class="full">
<div class="pull-left text-left">
<div class="menu-header-links-container">
<ul id="menu-header-links" class="menu">
<li class="a">Menu 1</li>
<li class="b">Menu 2 </li>
</ul>
</div>
<ul class="mini-menu-a">
<li>a</li>
<li>b</li>
</ul>
<div class="mini-menu-b">
<div class="footer-links clearfix">
<ul id="menu-footer-links" class="menu">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</div>
</div>
</div>
</div>
CSS:
.full {
z-index: 1;
background: #a97b3e;
padding: 30px 60px;
margin: 0;
width: 100%;
}
ul {
padding: 0;
margin: 0;
list-style: none;
}
ul li {
display: inline-block;
margin-right: 20px;
}
ul li a {
color: #fff;
}
.navbar.navbar-default .menu-header-links-container {
float: left;
padding: 30px 0;
}
.mini-menu-a,
.mini-menu-b {
border: 1px solid #fff;
display: none;
;
float: left;
list-style: none;
margin-left: 20px;
}
ul#menu-header-links {
float: left
}
sCRIPT:
$('.menu-header-links-container .a a').on('click', function() {
$(".mini-menu-a").toggle('slide');
$(".mini-menu-b").hide();
$(this).toggleClass('open-btn').removeClass('close-btn');
$(".menu-header-links-container .follow a").toggleClass('close-btn').removeClass('open-btn');
});
$('.menu-header-links-container .b a').on('click', function() {
$(".mini-menu-b").toggle('slide');
$(".mini-menu-a").hide();
$(this).toggleClass('open-btn').removeClass('close-btn');;
$(".menu-header-links-container .subscribe a").toggleClass('close-btn').removeClass('open-btn');
});
I'm using this reference.
JS Fiddle here
Is it possible to make the position absolute dropdown stay on top of the scrollable container, and move along with the position relative parent when scrolling? Right now, the dropdown appears within the scrollable area.
The screenshot below is what I want to achieve. I'm also open to javascript solutions if needed.
jsFiddle
.navbar {
padding-left: 0;
white-space: nowrap;
overflow: auto;
}
.navbar-item {
position: relative;
margin-left: 0;
list-style: none;
display: inline-block;
width: 200px;
text-align: center;
border: 1px solid;
}
.dropdown {
position: absolute;
padding-left: 0;
width: 200px;
box-shadow: 0 1px 0 1px black;
display: none;
}
.dropdown-item {
margin-left: 0;
list-style: none;
}
.navbar-item:hover .dropdown {
display: block;
}
<ul class="navbar">
<li class="navbar-item">
<a>Item A</a>
<ul class="dropdown">
<li class="dropdown-item">Sub Item A</li>
<li class="dropdown-item">Sub Item B</li>
<li class="dropdown-item">Sub Item C</li>
</ul>
</li>
<li class="navbar-item"><a>Item B</a></li>
<li class="navbar-item"><a>Item C</a></li>
<li class="navbar-item"><a>Item D</a></li>
<li class="navbar-item"><a>Item E</a></li>
</ul>
An easy way is to make the position of dropdown fixed, but make sure to apply the left and top values accordingly. Another way is to append the dropdown menu outside the ul element, so when it appears it will not be wrapped within it.
.dropdown {
position: fixed;
}
.navbar {
padding-left: 0;
white-space: nowrap;
overflow: auto;
}
.navbar-item {
position: relative;
margin-left: 0;
list-style: none;
display: inline-block;
width: 200px;
text-align: center;
border: 1px solid;
}
.dropdown {
position: fixed;
background-color: #fff;
padding-left: 0;
width: 200px;
box-shadow: 0 1px 0 1px black;
display: none;
}
.navbar-item {
margin-left: 0;
list-style: none;
}
.navbar-item:hover .dropdown {
display: block;
}
<ul class="navbar">
<li class="navbar-item">
<a>Item A</a>
<ul class="dropdown">
<li class="dropdown-item">Sub Item A</li>
<li class="dropdown-item">Sub Item B</li>
<li class="dropdown-item">Sub Item C</li>
</ul>
</li>
<li class="navbar-item"><a>Item B</a></li>
<li class="navbar-item"><a>Item C</a></li>
<li class="navbar-item"><a>Item D</a></li>
<li class="navbar-item"><a>Item E</a></li>
</ul>
Edit
I added one more snippet that does not use fixed position. It changes its coordinates when open based on the parent offset.
$('#menu1, #submenu1').mouseover(function(event) {
$('#submenu1').addClass("show").css($('#menu1').offset());
});
$('#menu1, #submenu1').mouseleave(function(event) {
$('#submenu1').removeClass("show");
});
.navbar {
padding-left: 0;
white-space: nowrap;
overflow: auto;
}
.navbar-item {
position: relative;
margin-left: 0;
list-style: none;
display: inline-block;
width: 200px;
text-align: center;
border: 1px solid;
}
.dropdown {
position: absolute;
padding-left: 0;
width: 200px;
box-shadow: 0 1px 0 1px black;
display: none;
}
.dropdown.show {
display: block;
margin-left: 1px;
background-color: #fff;
}
.dropdown-item {
margin-left: 0;
list-style: none;
}
.navbar-item:hover .dropdown {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="navbar">
<li id="menu1" class="navbar-item">
<a>Item A</a>
</li>
<li class="navbar-item"><a>Item B</a></li>
<li class="navbar-item"><a>Item C</a></li>
<li class="navbar-item"><a>Item D</a></li>
<li class="navbar-item"><a>Item E</a></li>
</ul>
<ul id="submenu1" class="dropdown">
<li class="dropdown-item">Sub Item A</li>
<li class="dropdown-item">Sub Item B</li>
<li class="dropdown-item">Sub Item C</li>
</ul>
Here's an option using jQuery.
Basically, as others have mentioned, you'll have to move the subnav items outside of the main nav's wrapper, so that they are not hidden.
We can put them in their own wrapper that has a similar markup to the main nav's wrapper, and then match them up using a data element to allow for showing/hiding on click.
Then, when we scroll the main navbar, we can sync the subnav wrapper to that element's scroll position, so the subnav items appear to be fixed to the main nav items.
Lastly, we can hide the subnav wrapper's scroll bar with CSS.
The snippet below should get you the general idea, then you can style it as necessary to make it look more like the primary and secondary nav items are connected.
Click a nav item in the main nav, then scroll to the side to see it in action:
$(function(){
var navbar = $('.navbar');
var subnavBar = $('.subnavs-wrapper .scrollbar-hider');
$(navbar).find('li').each(function(){
var dataId = $(this).attr('data-id');
var matchingUl = $(this).parent().next().find('ul[data-id="' + dataId + '"]');
$(this).on('click', function(){
$(matchingUl).css('visibility') == 'hidden' ?
$(matchingUl).css('visibility', 'visible') : $(matchingUl).css('visibility', 'hidden');
});
$(navbar).on('scroll', function(){
$(subnavBar).scrollLeft($(this).scrollLeft());
});
});
});
.navbar {
padding-left: 0;
white-space: nowrap;
overflow: auto;
display: flex;
}
.navbar-item {
position: relative;
margin-left: 0;
list-style: none;
flex-shrink: 0;
width: 200px;
text-align: center;
border: 1px solid;
}
.dropdown {
position: absolute;
padding-left: 0;
width: 200px;
box-shadow: 0 1px 0 1px black;
display: none;
}
.navbar-item {
margin-left: 0;
list-style: none;
}
.navbar-item:hover .dropdown {
display: block;
}
.subnavs-wrapper {
overflow: hidden; /* hide scrollbar */
}
.subnavs-wrapper .scrollbar-hider {
display: flex;
overflow: auto;
padding-bottom: 50px; /* hide scrollbar */
margin-bottom: -50px; /* hide scrollbar */
}
.subnav {
width: 200px;
padding-left: 0;
list-style: none;
visibility: hidden;
flex-shrink: 0;
border: 1px solid black;
}
<ul class="navbar">
<li class="navbar-item" data-id="one"><a>Item A</a>
<li class="navbar-item" data-id="two"><a>Item B</a></li>
<li class="navbar-item" data-id="three"><a>Item C</a></li>
<li class="navbar-item" data-id="four"><a>Item D</a></li>
<li class="navbar-item" data-id="five"><a>Item E</a></li>
</ul>
<div class="subnavs-wrapper">
<div class="scrollbar-hider">
<ul class="subnav" data-id="one">
<li>Sub Item A.A</li>
<li>Sub Item A.B</li>
<li>Sub Item A.C</li>
</ul>
<ul class="subnav" data-id="two">
<li><a>Sub Item B.A</a></li>
</ul>
<ul class="subnav" data-id="three">
<li><a>Sub Item C.A</a></li>
<li><a>Sub Item C.B</a></li>
</ul>
<ul class="subnav" data-id="four">
<li><a>Sub Item D.A</a></li>
<li><a>Sub Item D.B</a></li>
</ul>
<ul class="subnav" data-id="five">
<li><a>Sub Item E.A</a></li>
<li><a>Sub Item E.B</a></li>
</ul>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
Above is the result I want, each drop-down list is under the main title.
For example:
A1, A2, A3, A4 is under A when I click the expand collapse button.
B1, B2, B3, B4 is under B when I click the second expand collapse button.
But now my drop-down list is not aligned accordingly. You can check my code for more details. Hoping that some of you could provide me with some advice.
$(".es_epdtitle").click(function() {
$('.es_expandct').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".es_epdtitle1").click(function() {
$('.es_expandct1').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".es_epdtitle2").click(function() {
$('.es_expandct2').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
ul { list-style-type: none; margin:0; padding: 0; }
.eservices_left ul li{display:inline;}
.es_expandct, .es_expandct1, .es_expandct2 {
display: none;
position:absolute;
padding-top: 20px;
margin: 0 10px;
}
.es_epdtitle, .es_epdtitle1, .es_epdtitle2{
background:url('https://image.ibb.co/jUyN5Q/arrow_up_grey.png') no-repeat;
width: 30%;
float:left;
background-position:right 0px;
cursor:pointer;
background-color:#ccc;
margin: 0 10px;
}
.collapsed .es_epdtitle, .collapsed .es_epdtitle1, .collapsed .es_epdtitle2{
background-image:url('https://image.ibb.co/d669kQ/arrow_down_grey.png');
width: 30%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="mobexpand collapsed">
<div class="text_maroon_16_bold es_epdtitle">A</div>
<ul class="es_expandct">
<li>A1</li>
<li>A2</li>
</ul>
</li>
<li class="mobexpand collapsed">
<div class="text_maroon_16_bold es_epdtitle1">B</div>
<ul class="es_expandct1">
<li>B1</li>
<li>B2</li>
</ul>
</li>
<li class="mobexpand collapsed noborder">
<div class="text_maroon_16_bold es_epdtitle2">C</div>
<ul class="es_expandct2">
<li>C1</li>
<li>C2</li>
</ul>
</li>
</ul>
Add position:relative to parent to make the drop-down position according to it and move float and width from text_maroon_16.. to the parent mobexpand to maintain the width and the style
See code snippet:
$(".es_epdtitle").click(function() {
$('.es_expandct').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".es_epdtitle1").click(function() {
$('.es_expandct1').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".es_epdtitle2").click(function() {
$('.es_expandct2').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.eservices_left ul li {
display: inline;
}
.es_expandct,
.es_expandct1,
.es_expandct2 {
display: none;
position: absolute;
margin: 0 10px;
}
.es_epdtitle,
.es_epdtitle1,
.es_epdtitle2 {
background: url('https://image.ibb.co/jUyN5Q/arrow_up_grey.png') no-repeat;
background-position: right 0px;
cursor: pointer;
background-color: #ccc;
margin: 0 10px;
}
.collapsed .es_epdtitle,
.collapsed .es_epdtitle1,
.collapsed .es_epdtitle2 {
background-image: url('https://image.ibb.co/d669kQ/arrow_down_grey.png');
}
.mobexpand {
position: relative;
width: 30%;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="mobexpand collapsed">
<div class="text_maroon_16_bold es_epdtitle">A</div>
<ul class="es_expandct">
<li>A1</li>
<li>A2</li>
</ul>
</li>
<li class="mobexpand collapsed">
<div class="text_maroon_16_bold es_epdtitle1">B</div>
<ul class="es_expandct1">
<li>B1</li>
<li>B2</li>
</ul>
</li>
<li class="mobexpand collapsed noborder">
<div class="text_maroon_16_bold es_epdtitle2">C</div>
<ul class="es_expandct2">
<li>C1</li>
<li>C2</li>
</ul>
</li>
</ul>
You could always use flex:
$(".es_epdtitle").click(function() {
$('.es_expandct').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".es_epdtitle1").click(function() {
$('.es_expandct1').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".es_epdtitle2").click(function() {
$('.es_expandct2').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
* {
box-sizing: border-box;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.eservices_left ul li {
display: inline;
}
.es_expandct,
.es_expandct1,
.es_expandct2 {
display: none;
position: absolute;
padding: 5px;
}
.es_epdtitle,
.es_epdtitle1,
.es_epdtitle2 {
background: url('https://image.ibb.co/jUyN5Q/arrow_up_grey.png') no-repeat;
width: 100%;
background-position: right center;
cursor: pointer;
background-color: #ccc;
padding: 5px;
margin: 0;
}
.collapsed .es_epdtitle,
.collapsed .es_epdtitle1,
.collapsed .es_epdtitle2 {
background-image: url('https://image.ibb.co/d669kQ/arrow_down_grey.png');
}
.main-ul {
display: flex;
}
.mobexpand {
padding: 10px;
flex: 1 0 33.33%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="main-ul">
<li class="mobexpand collapsed">
<div class="text_maroon_16_bold es_epdtitle">A</div>
<ul class="es_expandct">
<li>A1</li>
<li>A2</li>
</ul>
</li>
<li class="mobexpand collapsed">
<div class="text_maroon_16_bold es_epdtitle1">B</div>
<ul class="es_expandct1">
<li>B1</li>
<li>B2</li>
</ul>
</li>
<li class="mobexpand collapsed noborder">
<div class="text_maroon_16_bold es_epdtitle2">C</div>
<ul class="es_expandct2">
<li>C1</li>
<li>C2</li>
</ul>
</li>
</ul>
Can anyone show me how I can achieve moving .showBorder and .box-tip when .clicked is selected. So when tab is selected the tabs below will have a border selected with above text moving along. only require one tab and one border to be selected at one time. Here's my code so far:
$(document).on("click", '.clicked', function(){
$('.clicked').removeClass('selected');
$(this).addClass('selected');
});
.list-box li {display: inline-block;list-style-type: none;padding: 1em;background:red;}
.list-box {margin:25px auto;padding:0;}
.box-sleeve li {display: inline-block;list-style-type: none;padding: 1em;background:red;}
.box-sleeve {margin:25px auto;padding:0;}
.showBorder { border: 3px dashed black; }
.box-tip {
display:inline;
margin: auto;
position: relative;
}
.numberCircle {
border-radius: 50%;
font-size: 12px;
border: 5px solid #000;
color: #fff;
background: #000;
}
.numberCircle span {
text-align: center;
display: block;
}
li.selected {color:#fff;background-color:#000;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<ul class="list-box">
<li class="clicked">1</li>
<li class="clicked">2</li>
<li class="clicked">3</li>
<li class="clicked">4</li>
<li class="clicked">5</li>
<li class="clicked">6</li>
<li class="clicked">7</li>
<li class="clicked">8</li>
</ul>
<div class="box-tip">
<span class="info">Regular length for your collar size</span>
<span class="numberCircle">?</span>
</div>
<ul class="box-sleeve">
<li class="border">a</li>
<li class="border">b</li>
<li class="border showBorder">c</li>
<li class="border">d</li>
<li class="border">e</li>
<li class="border">f</li>
<li class="border">g</li>
<li class="border">h</li>
</ul>
Use .index(element) to get the position of the element relative to its siblings.
Use .eq(index) to get the element at index position in another element.
So it would look like this:
$(document).on("click", '.clicked', function() {
var boxes = $('.list-box li'),
sleeves = $('.box-sleeve li'),
tip = $('.box-tip .info');
var currBox = $(this),
currSleeve = sleeves.eq(boxes.index(currBox));
// select box and sleeve
boxes.removeClass('selected');
currBox.addClass('selected');
sleeves.removeClass('showBorder');
currSleeve.addClass('showBorder');
// move tip
tip.css('left', currBox.position().left - 100);
});
.container {
/* to center both list */
text-align: center;
}
.list-box {
margin: 25px auto;
padding: 0;
}
.list-box li {
display: inline-block;
list-style-type: none;
padding: 1em;
background: red;
}
.list-box li.selected {
color: #fff;
background-color: #000;
}
.box-sleeve {
margin: 25px auto;
padding: 0;
}
.box-sleeve li {
display: inline-block;
list-style-type: none;
padding: 1em;
background: red;
}
.showBorder {
border: 3px dashed black;
}
.box-tip {
/*border: 1px solid #ddd;*/
position: relative;
height: 25px;
line-height: 25px;
}
.box-tip .info {
position: absolute;
/* to ensure that it one liner */
white-space: nowrap;
/* default text position */
left: 120px;
}
.numberCircle {
border-radius: 50%;
font-size: 12px;
border: 5px solid #000;
color: #fff;
background: #000;
}
.numberCircle span {
text-align: center;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- wrap everything in a container, so that we can center them -->
<div class="container">
<ul class="list-box">
<li class="clicked">1</li>
<li class="clicked">2</li>
<li class="clicked">3</li>
<li class="clicked">4</li>
<li class="clicked">5</li>
<li class="clicked">6</li>
<li class="clicked">7</li>
<li class="clicked">8</li>
</ul>
<div class="box-tip">
<!-- this will be absolutely positioned to have flexibility in moving it -->
<span class="info">Regular length for your collar size <span class="numberCircle">?</span></span>
</div>
<ul class="box-sleeve">
<li class="border">a</li>
<li class="border">b</li>
<li class="border">c</li>
<li class="border">d</li>
<li class="border">e</li>
<li class="border">f</li>
<li class="border">g</li>
<li class="border">h</li>
</ul>
</div>
Edit
You can use .position() to get the position of your selected box and use it to calculate the position of the .box-tip. Though, you'll notice it requires some changes to the HTML and CSS (see comments) to ensure that it is always centered.
I want to add a active function to the current menu item on page scroll. It’s a single page with different sections. When click on an item, the active state should switch to the current one.
As you scroll down the page, the active menu item changes. How is this done? Would guys give me a answer base on my demo coding? Thanks.
My demo: http://jsfiddle.net/x2skzp1p/1/
var menuContainer = $('header').height();
function scrollToAnchor(anchorName) {
var aTag = $("div[name='" + anchorName + "']");
$('html,body').animate({
scrollTop: aTag.offset().top - menuContainer
}, 'slow');
console.log(anchorName);
}
.fluid {
clear: both;
margin-left: 0;
width: 100%;
float: left;
display: block;
}
/* Mobile Layout: 480px and below. */
body {
background-color: #EEEEEE;
font-family: "Open Sans", Helvetica, "Heiti TC", "Microsoft JhengHei", "Microsoft Yahei", "PMingLiU", sans-serif;
font-size: 100%;
margin-top: 0px;
}
.gridContainer {
margin-left: auto;
margin-right: auto;
padding-left: 1.1375%;
padding-right: 1.1375%;
clear: none;
float: none;
width: auto;
}
#header {
margin-top: 0;
margin-right: auto;
margin-left: auto;
display: block;
width: 100%;
height: 200px;
max-width: 1000px;
position: fixed;
background-color: #FF6600;
}
/* header - navigation */
#subnav {
height: 100%;
margin-right: auto;
width: 100%;
background-color: #1BBC9B;
font-size: 120%;
}
#navmenu ul {
padding: 0;
margin-top: 4px;
margin-right: auto;
margin-left: 0%;
margin-bottom: 0;
width: 650px;
}
#navmenu li {
display: inline;
float: left;
}
#navmenu a {
color: #294C52;
display: inline-block;
padding: 10px 20px;
text-align: center;
text-decoration: none;
font-weight: bold;
}
#navmenu li a {
border-right: 1px solid #294C52;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
#navmenu li:last-child a {
border-right: 1px solid #576979;
/* no border on last list item */
}
#navmenu li:first-child a {
background-color: #294C52;
color: #FFFFFF;
}
#navmenu a:hover,
nav a:active {
background-color: #1BBC9B;
color: #FFFFFF;
}
#content {
width: 100%;
max-width: 1000px;
height: 100%;
margin-top: 1px;
}
#section1 {
background-color: #294C52;
width: 100%;
display: block;
padding-top: 5px;
padding-bottom: 5px;
margin-top: 198px;
}
#section2 {
background-color: #EEEEEE;
}
#section3 {
background-color: #EEEEEE;
}
#section4 {
background-color: #EEEEEE;
margin-left: 0;
width: 100%;
float: left;
}
#content-about-org-left {
width: 48.1012%;
background-color: #FFFFFF;
float: left;
clear: none;
}
#content-about-org-centre {
width: 48.1012%;
margin-left: 1.2658%;
clear: none;
background-color: #FFFFFF;
float: right;
}
#content-about-org-right {
background-color: #FFFFFF;
}
#section5 {
background-color: #EEEEEE;
}
/* content - typography */
.content-list {
list-style-type: none;
color: #294C52;
text-indent: -25px;
font-size: 100%;
line-height: 173%;
}
.content-list-bold {
font-weight: bolder;
font-size: 110%;
color: #294C52;
}
.content-title {
background-color: #903233;
color: #FFFFFF;
padding-top: 3px;
}
.content-p-white {
color: #FFFFFF;
padding-left: 10px;
padding-right: 10px;
text-align: justify;
line-height: 25px;
padding-top: 0px;
padding-bottom: 0px;
}
.content-p-black {
color: #294C52;
padding-left: 10px;
padding-right: 10px;
text-align: justify;
line-height: 25px;
font-size: 100%;
}
.content-p-black-b {
color: #294C52;
font-weight: bolder;
padding-left: 10px;
font-size: 110%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gridContainer clearfix">
<header id="header">
<nav id="subnav" class="fluid">
<ul id="navmenu">
<li><a onClick="scrollToAnchor('section1');" title="成立背景">SECTION 1</a>
</li>
<li><a onClick="scrollToAnchor('section2');" title="協會使命">SECTION 2</a>
</li>
<li><a onClick="scrollToAnchor('section3');" title="營運模式">SECTION 3</a>
</li>
<li><a onClick="scrollToAnchor('section4');" title="協會組織">SECTION 4</a>
</li>
<li><a onClick="scrollToAnchor('section5');" title="活動及刊物">SECTION 5</a>
</li>
</ul>
</nav>
</header>
<!--end of header-->
<!--start of content-->
<div class="fluid" id="content">
<div id="section1" class="fluid" name="section1">
<p class="content-p-white">《2013年香港殘疾人士貧窮情況報告》顯示介乎18至64歲適齡工作的殘疾人士的貧窮率為22.4%,遠較相同年齡群的整體貧窮率10.5%為高。再者,按經濟活動身分劃分,近18萬名的殘疾適齡工作人士當中,只有39.1%有從事經濟活動,遠低於整體人口中同年齡層的72.8%。</p>
<p class="content-p-white">於2013年3月初,一群熱心人士包括郭鍵勳博士、謝俊謙教授及伍杏修先生等有意建立一個各方協作平台,改善殘疾人士的就業困難。</p>
<p class="content-p-white">資訊科技易達協會有限公司 Accessible IT Development Association Limited (AIDA) 於2014年11月正式註冊成立。</p>
<!--<div id="secttion1-bg"></div>--></div>
<!--end of section1-->
<div id="section2" class="fluid" name="section2">
<article>
<h2 class="content-title"> SECTION 2</h2>
<p class="content-p-black">資訊科技易達協會是一個社會企業致力提供專業資訊科技服務,同時為嚴重殘疾人士提供培訓及工作機會,讓學員可選擇在家居從事資訊科技相關工作;協會全力推動無障礙軟件開發,協助社會資訊共融。</p>
</article>
</div>
<!--end of section2-->
<div id="section3" class="fluid" name="section3">
<article>
<h2 class="content-title"> SECTION 3</h2>
<figure>
<img src="images/2-about-us_03.jpg" alt="營運模式示意圖" class="alignRight" title="營運模式示意圖" />
</figure>
<p class="content-p-black">全面利用現代通訊科技的便利,解決殘疾人士面對指定工作地點的限制,讓他們可選擇在家居或院舍工作,同時得到必要的護理。AIDA選擇網頁開發作為起步點,由「無障礙學堂」(Barrier-Free School) 及業界專業義工負責培訓學員,讓他們掌握指定技術。</p>
<p class="content-p-black">AIDA會承接工作項目,將項目分拆,然後將組件分配給技術程度不同的學員,並會密切督導整個項目的進行。AIDA已經與本地多間知名網頁開發公司結為合作伙伴,致力確保AIDA的所有服務均符合市場要求。AIDA會以殘疾友善機構的工作項目作為開始,當累積一定成功往績後,會推廣至主流市場。</p>
</article>
</div>
<!--end of section3-->
<div id="section4" class="fluid" name="section4">
<article>
<h2 class="content-title"> SECTION 4</h2>
<div id="content-about-org-left" class="fluid">
<ul class="content-list">
<li class="content-list-bold">名譽贊助人</li>
<li>謝俊謙教授</li>
<li class="content-list-bold">主席</li>
<li>郭鍵勳博士</li>
<li class="content-list-bold">副主席</li>
<li>劉海軍先生</li>
<li class="content-list-bold">義務秘書</li>
<li>伍杏修先生</li>
<li class="content-list-bold">義務司庫</li>
<li>郭皓君女士</li>
<li class="content-list-bold">核數師</li>
<li></li>
<li class="content-list-bold">義務法律顧問</li>
<li>林子絪女士</li>
<li class="content-list-bold">義務總幹事</li>
<li>蘇炳坤先生</li>
<li class="content-list-bold">諮詢委員及指導</li>
<li></li>
</ul>
</div>
<div id="content-about-org-centre" class="fluid">
<ul class="content-list">
<li class="content-list-bold">董事</li>
<li>張健輝先生</li>
<li>郭鍵勳博士</li>
<li>郭皓君女士</li>
<li>劉海軍先生</li>
<li>羅偉祥先生</li>
<li>伍杏修先生</li>
<li>吳家榮博士</li>
<li>蘇炳坤先生</li>
<li>謝俊謙教授</li>
<li>黃婉冰女士</li>
<li>游寶榮先生</li>
</ul>
</div>
<div id="content-about-org-right" class="fluid">
<ul class="content-list">
<li class="content-list-bold">工作團隊</li>
<li>王乃東 王迪清 江啟暉 利詠然 李俊輝</li>
<li>李豪飛 冼永健 何浚彥 施嶸傑 翁文菁</li>
<li>茹文祥 郭寧 章世恒 曾志豪 曾鈴茵</li>
<li>黃新陽 蔡冀逵 鄭建慧 盧兆豐</li>
</ul>
<p>
<img src="images/2-about-us_06.jpg" alt="工作團隊成員相片" title="工作團隊成員相片" />
</p>
</div>
</article>
</div>
<!--end of section4-->
<div id="section5" class="fluid" name="section5">
<article>
<h2 class="content-title"> SECTION 5</h2>
<ul class="content-list">
<li class="content-list-bold">新春團拜</li>
<li>日期︰2015年3月14日(星期六)</li>
<li>地點︰金鐘添馬公園添馬茶座愛烘焙餐廳</li>
<li>時間︰下午4:00- 5:30</li>
</ul>
<hr>
<ul class="content-list">
<li class="content-list-bold">第一次周年大會</li>
<li>日期︰2015年3月14日(星期六)</li>
<li>地點︰金鐘添馬公園添馬茶座愛烘焙餐廳</li>
<li>時間︰下午3:30- 4:00</li>
</ul>
<hr>
<ul class="content-list">
<li class="content-list-bold">協會發展成長分享會</li>
<li>日期︰2015年2月3日(星期二)</li>
<li>地點︰金鐘添馬公園添馬茶座愛烘焙餐廳</li>
<li>時間︰上午11:00- 下午4:00</li>
<li>內容:</li>
<li>1. Delifrance午膳</li>
<li>2. 匯報協會最新發展,就大家感興趣的事務進行商討</li>
<li>3. IT人Ben Wong 個人經歷分享</li>
<li>4. 參觀香港大學校園或自由活動</li>
</ul>
<hr>
<ul class="content-list">
<li class="content-list-bold">協會發展成長分享會</li>
<li>日期︰2015年2月3日(星期二)</li>
<li>地點︰金鐘添馬公園添馬茶座愛烘焙餐廳</li>
<li>時間︰上午11:00- 下午4:00</li>
<li>內容:</li>
<li>1. Delifrance午膳</li>
<li>2. 匯報協會最新發展,就大家感興趣的事務進行商討</li>
<li>3. IT人Ben Wong 個人經歷分享</li>
<li>4. 參觀香港大學校園或自由活動</li>
</ul>
<hr>
</article>
</div>
<!--end of section5-->
</div>
<!--end of content-->
</div>
<!--end of gridContainer-->
$(document).ready( function (){
var topMenu = $("#navmenu"),
topMenuHeight = topMenu.outerHeight()+15,
// All list items
menuItems = topMenu.find("a"),
// Anchors corresponding to menu items
scrollItems = menuItems.map(function(){
var item = $($(this).attr("href"));
if (item.length) { return item; }
});
});
// Bind to scroll
$(window).scroll(function(){
// Get container scroll position
var fromTop = $(this).scrollTop()+topMenuHeight;
// Get id of current scroll item
var cur = scrollItems.map(function(){
if ($(this).offset().top < fromTop)
return this;
});
// Get the id of the current element
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
// Set/remove active class
menuItems.parent().removeClass("active")
.end().filter("[href=#"+id+"]").parent().addClass("active");
});
<header id="header">
<nav id="subnav" class="fluid">
<ul id="navmenu">
<li>SECTION 1</li>
<li>SECTION 2</li>
<li>SECTION 3</li>
<li>SECTION 4</li>
<li>SECTION 5</li>
</ul>
</nav>
</header>
and add this style
#navmenu li a .active {
background-color: #294C52;
color: #FFFFFF;
}
You can use onscroll event to set active div and an active class to set it:
$(function () {
$("body").onscroll(function () {
$("#navmenu li").removeClass("active");
if ($("body").scrollTop() > $("#section5").offset().top)
$("#navmenu li").eq(4).addClass("active");
else if ($("body").scrollTop() > $("#section4").offset().top)
$("#navmenu li").eq(3).addClass("active");
else if ($("body").scrollTop() > $("#section3").offset().top)
$("#navmenu li").eq(2).addClass("active");
else if ($("body").scrollTop() > $("#section2").offset().top)
$("#navmenu li").eq(1).addClass("active");
else
$("#navmenu li").eq(0).addClass("active");
});
});