Let's say we have a navigation div which contains elements. Below navigation div there is some bar that must expand to the width where it matches one of the navigation elements (3rd one in this case).
<div id="main_navigator">
<div id="main_navigator_upper">
<a id="main_navigator_logo" src="/"></a>
<ul id="main_navigator_r1">
<li>
<a class="main_nav_btn">BTN 1</a>
</li>
<li>
<a class="main_nav_btn">BTN 2</a>
</li>
<li>
<a class="main_nav_btn">BTN 3</a>
</li>
<li>
<a class="main_nav_btn">BTN 4</a>
</li>
<li id="main_navigator_l1">
<div id="main_navigator_s1"></div>
</li>
<li>
<ul id="main_navigator_regbox">
<li>
<p id="regbox_signin">sign in</p>
</li>
<li>
<div id="main_navigator_regbox_s1"></div>
</li>
<li>
<a id="regbox_signup" href="sign_up">sign up</a>
</li>
</ul>
</li>
</ul>
</div>
<div id="main_navigator_bottom">
<div id="main_navigator_progression"></div>
</div>
</div>
From this code, main_navigator_progression div must expand its width so it matches BTN 3.
You can see the concept here.
I've written a simple JS code, but it doesn't seem to be neat and doesn't always work:
function initializeProgressorPos() {
document.getElementById("main_navigator_progression").setAttribute("style", ("width: " + (document.getElementsByClassName("main_nav_btn")[2].getBoundingClientRect().x - document.getElementsByClassName("main_nav_btn")[2].getBoundingClientRect().width) + "px"))
}
initializeProgressorPos();
$(window).resize(function() {
initializeProgressorPos();
});
Is there any way to create such a function that works even when browser is scaled? What could be wrong with my code? Is there any chance that this can be done with pure css?
As you have floatted the element to the right, first you have to get the width of document, then exclude the width from left of document to the right of element from that amount:
function initializeProgressorPos() {
var elementRight=$(document).width()- $('.main_nav_btn:eq(2)').offset().left - $('.main_nav_btn:eq(2)').width();
$("#main_navigator_progression").css({"width": elementRight + "px"});
}
initializeProgressorPos();
$(window).resize(function() {
initializeProgressorPos();
});
body {
margin: 0;
overflow-y: scroll;
}
#main_navigator {
position: fixed;
background-color: black;
width: 100%;
}
#main_navigator_upper {
position: relative;
display: flex;
flex-direction: row;
}
#main_navigator_logo {
width: 416px;
height: 120px;
background-color: white;
}
#main_navigator_r1 {
display: flex;
flex-direction: row;
align-items: center;
flex-grow: 1;
flex-shrink: 1;
padding: 0;
padding-right: 5%;
text-align: center;
margin-top: 0px;
height: 98px;
list-style-type: none;
}
#main_navigator_r1 li {
flex-grow: 1;
flex-shrink: 1;
/* flex-basis: 0; */
flex-basis: auto; /* new */
}
#main_navigator_l1 {
flex-grow: 0.1 !important;
}
#main_navigator_r1 li .main_nav_btn {
color: white;
display: block;
height: 100%;
font-family: "nexa_bold";
font-size: 0.9em;
text-decoration: none;
}
#main_navigator_s1 {
display: inline-block;
width: 2px;
height: 35px;
background-color: #B28039;
}
#main_navigator_regbox {
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
list-style-type: none;
margin: 0px;
padding: 0px;
}
#main_navigator_regbox li {
display: inline-block;
flex-grow: 0.1;
flex-shrink: 0.1;
}
#regbox_signin {
display: block;
cursor: pointer;
white-space: nowrap;
text-decoration: none;
color: #B28039;
font-size: 0.9em;
font-family: "nexa_light";
}
#regbox_signup {
display: block;
white-space: nowrap;
text-decoration: none;
color: white;
font-size: 0.9em;
font-family: "nexa_light";
}
#main_navigator_regbox_s1 {
display: inline-block;
width: 1.4px;
height: 13.5px;
background-color: white;
}
#main_navigator_bottom {
background-color: black;
height: 24px;
}
#main_navigator_progression {
position: relative;
background-color: #B28039;
height: 100%;
width: 416px;
float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="main_navigator">
<div id="main_navigator_upper">
<a id="main_navigator_logo" src="/"></a>
<ul id="main_navigator_r1">
<li>
<a class="main_nav_btn">BTN 1</a>
</li>
<li>
<a class="main_nav_btn">BTN 2</a>
</li>
<li>
<a class="main_nav_btn">BTN 3</a>
</li>
<li>
<a class="main_nav_btn">BTN 4</a>
</li>
<li id="main_navigator_l1">
<div id="main_navigator_s1"></div>
</li>
<li>
<ul id="main_navigator_regbox">
<li>
<p id="regbox_signin">sign in</p>
</li>
<li>
<div id="main_navigator_regbox_s1"></div>
</li>
<li>
<a id="regbox_signup" href="sign_up">sign up</a>
</li>
</ul>
</li>
</ul>
</div>
<div id="main_navigator_bottom">
<div id="main_navigator_progression"></div>
</div>
</div>
</body>
</html>
This is a proof of concept.
You can use a combination of a custom HTML5 data-* attribute and an ::after pseudo-element on your navigation menu (and a dash of javascript) to indicate which menu item you have most recently selected.
Despite the dash of javascript, most of the work is done using CSS.
Working Example:
var menu = document.querySelector('nav ul');
var menuItems = [... menu.getElementsByTagName('li')];
function selectMenu() {
menu.dataset.selectedMenu = (menuItems.indexOf(this) + 1);
}
for (var i = 0; i < menuItems.length; i++) {
menuItems[i].addEventListener('click', selectMenu, false);
}
nav ul {
display: flex;
position: relative;
margin: 0;
padding: 0;
}
nav li {
flex: 0 0 60px;
padding: 12px 12px 24px;
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
list-style-type: none;
cursor: pointer;
}
nav ul::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
height: 12px;
background-color: rgba(0, 0, 0, 0.5);
transition: width 0.6s linear;
}
nav ul[data-selected-menu="1"]::after {
width: 80px;
}
nav ul[data-selected-menu="2"]::after {
width: 160px;
}
nav ul[data-selected-menu="3"]::after {
width: 240px;
}
nav ul[data-selected-menu="4"]::after {
width: 320px;
}
nav ul[data-selected-menu="5"]::after {
width: 400px;
}
<nav>
<ul data-selected-menu="1">
<li class="active">Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
<li>Menu 5</li>
</ul>
</nav>
Related
I have a project that when I click titleA, all blocks of titleA must be added with a yellow style, and when titleB is clicked, a yellow style must be added to the titleB page, and the yellow style of titleA will be removed!
But I don’t know this. How to achieve the effect, I need some help from everyone, thank you.
$('#js-title1').on('click',function(){
$('#js-title1').addClass('active'); //點擊到的增加樣式
$('#js-title2').removeClass('active') //同層其他元素移除樣式
})
body {
padding: 30px;
}
.wrap {
display: flex;
margin-bottom: 100px;
}
.wrap .demo {
font-weight: 900;
margin: 30px;
text-decoration: none;
color: #222;
}
.wrap-2 {
display: flex;
}
.wrap-2 .demo {
font-weight: 900;
margin: 30px;
text-decoration: none;
color: #222;
}
.active {
position: relative;
}
.active::after {
content: "";
position: absolute;
bottom: 2px;
left: 0;
right: 0;
display: block;
width: 50px;
height: 8px;
background: #FFEB50;
z-index: -1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="wrap">
<li>
titleA
</li>
<li>
titleB
</li>
</ul>
<ul class="wrap-2">
<li>
titleA
</li>
<li>
titleB
</li>
</ul>
There are multiple js-title1 & js-title2, do not use ID, consider to use css class name.
$('.js-title1').on('click',function(){
$('.js-title1').addClass('active'); //點擊到的增加樣式
$('.js-title2').removeClass('active') //同層其他元素移除樣式
})
$('.js-title2').on('click',function(){
$('.js-title2').addClass('active'); //點擊到的增加樣式
$('.js-title1').removeClass('active') //同層其他元素移除樣式
})
body {
padding: 30px;
}
.wrap {
display: flex;
margin-bottom: 100px;
}
.wrap .demo {
font-weight: 900;
margin: 30px;
text-decoration: none;
color: #222;
}
.wrap-2 {
display: flex;
}
.wrap-2 .demo {
font-weight: 900;
margin: 30px;
text-decoration: none;
color: #222;
}
.active {
position: relative;
}
.active::after {
content: "";
position: absolute;
bottom: 2px;
left: 0;
right: 0;
display: block;
width: 50px;
height: 8px;
background: #FFEB50;
z-index: -1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="wrap">
<li>
titleA
</li>
<li>
titleB
</li>
</ul>
<ul class="wrap-2">
<li>
titleA
</li>
<li>
titleB
</li>
</ul>
IDs must be unique. You can't have more than one on the same page. Perhaps use a data attribute instead. Here's a stripped down example.
// When any title is clicked on
$('.demo').on('click', function() {
// Get the id from the dataset
const id = $(this).data('id');
// Remove all the active classes
$('.demo').removeClass('active');
// Add a class to all those elements that
// have a data-id that matches the id
$(`[data-id="${id}"`).addClass('active');
});
.active { background: #FFEB50; }
.demo:hover { cursor: pointer; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="demo" data-id="js-title1">titleA</a>
<a class="demo" data-id="js-title2">titleB</a>
<a class="demo" data-id="js-title1">titleA</a>
<a class="demo" data-id="js-title2">titleB</a>
Additional documentation
Template/string literals
Instead of the id attribute use the class attribute
and in jQuery, get the elements with . instead of #
Other than unique ids you should use ‘event.currentTarget’ or ‘$(this)’ to refer to the element and can use ‘.toggleClass()’ to toggle classes. This will simplify the code and logic.
const groups=[$("[id=js-title2]"), $("[id~='js-title1']")]
groups[0].on('click',function(e){
groups[0].toggleClass('active');
groups[1].removeClass('active');
})
groups[1].on('click',function(e){
groups[0].removeClass('active');
groups[1].toggleClass('active');
})
body {
padding: 30px;
}
.wrap {
display: flex;
margin-bottom: 100px;
}
.wrap .demo {
font-weight: 900;
margin: 30px;
text-decoration: none;
color: #222;
}
.wrap-2 {
display: flex;
}
.wrap-2 .demo {
font-weight: 900;
margin: 30px;
text-decoration: none;
color: #222;
}
.active {
position: relative;
}
.active::after {
content: "";
position: absolute;
bottom: 2px;
left: 0;
right: 0;
display: block;
width: 50px;
height: 8px;
background: #FFEB50;
z-index: -1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="wrap">
<li>
titleA
</li>
<li>
titleB
</li>
</ul>
<ul class="wrap-2">
<li>
titleA
</li>
<li>
titleB
</li>
</ul>
I'm trying to hide a mobile nav menu when the user resizes the screen past a certain point (767px). I thought this would be fairly straight-forward, but I can't get it to work. Any suggestions?
ps My constrainNav function is being called in the body tag (not shown).
// Toggle between hamburger and full mobile menu //
const nav = document.getElementById("mobile-nav");
const hamburger = document.getElementById("hamburger");
const width = window.innerWidth;
function navToggle() {
if (nav.style.display === "") {
nav.style.display = "block";
} else {
nav.style.display = "";
}
}
// Keep mobile-nav visible only when 767px or less
function constrainNav() {
if (nav && width > 767) {
nav.style.display = "none";
}
}
<nav class="nav">
<div id="navbar" class="nav__navbar"">
<div class="nav__left">
<img src="src/assets/img/Grieve-logo.png" class="nav__img" alt="grieve logo">
</div>
<div class="nav__right">
<ul class="nav__list">
<li class="nav__list-item"><a class="nav__list__link" href="#">Wines</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">Vineyard</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">About</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">Winemaker</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">Visit</a></li>
<li class="nav__list-item"><a class="nav__list__link" href="#">Buy</a></li>
</ul>
<i class="fa fa-bars"></i>
</div>
<div class="nav__navbar nav__navbar--mobile" id="mobile-nav">
<div class="nav__left nav__left--mobile">
<img src="src/assets/img/XXXXXX-logo.png" class="nav__img" alt="XXXXX logo">
<i class="fa fa-bars"></i>
</div>
<ul class="nav__list--mobile">
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Wines</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Vineyard</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">About</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Winemaker</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Visit</a></li>
<li class="nav__list__item--mobile"><a class="nav__list__link--mobile" href="#">Buy</a></li>
</ul>
</div>
</div>
</nav>
.nav {
position: sticky; // * curious to see how this works once we get to browser testing.
top: 0;
margin-top: -3px; // * necessary maybe? Not sure how to get rid of that small gap above the nav.
height: 100%;
&__navbar {
width: 100%;
overflow: hidden;
height: 3rem;
background-color: $colorPrimary;
display: flex;
justify-content: space-between;
padding: 0 1.5rem;
align-items: center;
&--mobile {
display: none;
position: absolute;
top: -17.625rem;
left: 0;
background-color: $colorSecondary;
max-width: 100%;
height: auto;
}
}
&__left {
color: $colorWhite;
margin: 0.75rem 0 0 0;
&--mobile {
display: flex;
justify-content: space-between;
}
}
&__img {
width: 5.625rem;
}
&__right {
margin: 0;
}
&__hamburger {
display: none;
color: $colorWhite;
margin: 0;
#include respond(med) {
display: block;
}
}
&__list {
list-style: none;
display: flex;
text-transform: uppercase;
justify-content: center;
#include respond(med) {
display: none;
}
&--mobile {
display: flex;
flex-direction: column;
list-style: none;
padding: 8rem 0;
align-items: center;
}
&__link {
text-decoration: none;
color: $colorWhite;
cursor: pointer;
text-transform: uppercase;
font-size: 1rem;
margin: 0 1rem;
#media (max-width: 40.625rem) {
margin: 0 0.5rem;
}
&--mobile {
text-decoration: none;
color: $colorWhite;
cursor: pointer;
text-transform: uppercase;
font-size: 1rem;
margin: 0 1rem;
#include respond(med) {
font-size: 2rem;
}
}
}
&__item {
&--mobile {
padding: 2rem;
}
}
}
}
I think this should be enough code. I can provide more. Thanks!
use css media query, in this case you dont need javascript.
#media screen and (min-width: 767px) {
.nav {
display: none
}
}
I'm trying to create a horizontal dropdown (err.. dropside?).
When clicked, it expands to the right to show more options, and the user can click the option they want.
I have found this JsFiddle but it is implemented using ul and li, not select and option. Does this really matter for the purposes of clicking a menu item and dispatching an action? It also expands on hover, not on click. And when a menu item is clicked, I need the menu to stay open until the 'X' on the left is clicked. If anyone could help me start on this it would be much appreciated.
Here's an image of what I'm trying to do
Try something like this:
[...document.getElementsByClassName("item")].forEach(i => i.addEventListener("click", function(e) {
e.stopPropagation();
console.log(this);
}));
document.getElementById("open-button").addEventListener("click", function() {
this.parentElement.classList.add("open");
});
document.getElementById("close-button").addEventListener("click", function() {
this.parentElement.classList.remove("open");
});
body {
background: black;
}
.menu {
background: white;
border-radius: 17px;
height: 34px;
width: 100px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
cursor: pointer;
}
.menu .item {
display: none;
color: grey;
}
.menu #open-button {
display: block;
}
.menu #close-button {
display: none;
color: grey;
}
.menu.open {
justify-content: space-around;
width: 300px;
}
.menu.open .item {
display: block;
}
.menu.open .item:hover {
color: black;
}
.menu.open #close-button {
display: block;
}
.menu.open #close-button:hover {
color: black;
}
.menu.open #open-button {
display: none;
}
<div class="menu">
<div id="open-button">Menu</div>
<div id="close-button">✕</div>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div>
if you for some reason have to use select and option in your markup here's how to do it, but it's a lot of work https://www.w3schools.com/howto/howto_custom_select.asp
or you can do something like this:
var btnToggle = document.querySelector(".js-toggle");
btnToggle.addEventListener("click", handleMenu);
function handleMenu() {
var menu = document.querySelector(".js-menu");
if ( menu.classList.contains("is-showing") )
{
menu.classList.remove("is-showing");
}
else
{
menu.classList.add("is-showing");
}
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background: #333;
}
.navigation {
background: #fff;
border-radius: 9999px;
display: inline-flex;
align-items: center;
padding: 20px;
}
.menu {
list-style: none;
padding-left: 22px;
margin: auto;
display: none;
}
.menu.is-showing {
display: inline-flex;
}
.menu__item {
background: #fff;
}
.box {
display: block;
background: #999;
width: 60px;
height: 60px;
margin: 0 22px;
}
.box:hover {
background: #498cdf;
}
.toggle {
padding: 0;
background: #e7e7e7;
border: none;
width: 60px;
height: 60px;
}
<div class="navigation">
<button class="toggle js-toggle">x</button>
<ul class="menu js-menu">
<li class="menu__item">
<span class="box"></span>
</li>
<li class="menu__item">
<span class="box"></span>
</li>
<li class="menu__item">
<span class="box"></span>
</li>
<li class="menu__item">
<span class="box"></span>
</li>
<li class="menu__item">
<span class="box"></span>
</li>
<li class="menu__item">
<span class="box"></span>
</li>
<li class="menu__item">
<span class="box"></span>
</li>
<li class="menu__item">
<span class="box"></span>
</li>
</ul>
</div>
Try this
<nav>
<a class="nav-btn">Logo</a>
<ul>
<li>Menu 1</li>
<li>Menu 1</li>
<li>Menu 1</li>
<li>Menu 1</li>
<li>Menu 1</li>
</ul>
</nav>
a, li {
display: block;
width: 100px;
height: 100px;
background-color: red;
float: left;
border: 1px solid yellow;
padding: 0;
margin: 0;
}
ul {
margin: 0;
padding: 0;
display: none;
}
.expand{
display: block;
}
$("nav .nav-btn").click(function(){
$("nav ul").toggleClass("expand");
});
a, li {
display: block;
width: 100px;
height: 100px;
background-color: red;
float: left;
border: 1px solid yellow;
padding: 0;
margin: 0;
}
ul {
margin: 0;
padding: 0;
display: none;
}
.expand{
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<a class="nav-btn">Logo</a>
<ul>
<li>Menu 1</li>
<li>Menu 1</li>
<li>Menu 1</li>
<li>Menu 1</li>
<li>Menu 1</li>
</ul>
</nav>
Im setting up a onclick dropdown navigation bar for the mobile part of my website, The problem im having is when it takes a double click in order for it to drop down. The result I want is for it to drop down on the first click.
The only thing I've tried so far is a Javascript function that I will show in my code.
function myFunction() {
var x = document.getElementById("submenu1");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function myFunction_2() {
var y = document.getElementById("submenu2");
if (y.style.display === "none") {
y.style.display = "block";
} else {
y.style.display = "none";
}
}
.main-nav {
display: flex;
}
.main-nav ul {
display: flex;
flex-wrap: wrap;
flex: 1;
list-style: none;
}
.main-nav li {
text-align: center;
position: relative;
width: 100%;
border-bottom: 1px solid white;
}
#submenu1 .submenu1-li:first-of-type {
border-top: 1px solid white;
}
.main-nav a {
display: flex;
display: block;
align-items: center;
justify-content: center;
flex: 1;
color: #fff;
background-color: #000;
padding: 5% 0%;
}
.submenu1-li {
position: absolute;
top: 0px;
}
#submenu1 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
.submenu2-li {
position: absolute;
top: 0px;
}
#submenu2 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
#submenu2 .submenu2-li:first-of-type {
border-top: 1px solid white;
}
#active {
background-color: #ffffff;
color: #000000;
height: 100%;
}
#submenu1 a:hover {
color: black;
background-color: white;
}
#desktop-port-move:hover #submenu2 {
display: block;
}
<nav class="main-nav">
<ul>
<li>
<a id="hide" href="javascript:void(0)" onclick="myFunction()">Menu
<span class="arrow">▼</span>
</a>
<ul id="submenu1">
<li class="submenu1-li">
<a id="active" href="home.html">Home</a>
</li>
<li class="submenu1-li">
About
</li>
<li id="desktop-contact-move" class="submenu1-li" >
Contact
</li>
<li id="desktop-port-move" class="submenu1-li" style:"order: 1;">
<a href="javascript:void(0)" onclick="myFunction_2();">Portfolio
<span class="arrow">▼</span>
</a>
<ul id="submenu2">
<li class="submenu2-li">
Designs
</li>
<li class="submenu2-li">
Websites
</li>
<li class="submenu2-li">
Photography
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
I expect the output to be a dropdown menu that responds on first click.
but the output im getting is a dropdown menu that responds on the second click, which is wrong for what I want.
Thanks in advance
and blessings to those who help
The reason it's not showing on the first click is that this condition
if (x.style.display === "none")
is false since you've set display: none; in CSS stylesheet. So a really quick way to fix this would be to add display: none; inline:
<ul id="submenu1" style="display:none;">
But a cleaner way would be to use classes to control menu visibility. See the snippet below.
function myFunction() {
var x = document.getElementById("submenu1");
x.classList.toggle('hidden');
}
.main-nav {
display: flex;
}
.main-nav ul {
display: flex;
flex-wrap: wrap;
flex: 1;
list-style: none;
}
.main-nav li {
text-align: center;
position: relative;
width: 100%;
border-bottom: 1px solid white;
}
#submenu1 .submenu1-li:first-of-type {
border-top: 1px solid white;
}
.main-nav a {
display: flex;
display: block;
align-items: center;
justify-content: center;
flex: 1;
color: #fff;
background-color: #000;
padding: 5% 0%;
}
.submenu1-li {
position: absolute;
top: 0px;
}
#submenu1 {
flex-direction: column;
position: absolute;
width: 100%;
}
#submenu1.hidden {
display: none;
}
.submenu2-li {
position: absolute;
top: 0px;
}
#submenu2 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
#submenu2 .submenu2-li:first-of-type {
border-top: 1px solid white;
}
#active {
background-color: #ffffff;
color: #000000;
height: 100%;
}
#submenu1 a:hover {
color: black;
background-color: white;
}
#desktop-port-move:hover #submenu2 {
display: block;
}
<nav class="main-nav">
<ul>
<li>
<a id="hide" href="javascript:void(0)" onclick="myFunction()">Menu
<span class="arrow">▼</span>
</a>
<ul id="submenu1" class="hidden">
<li class="submenu1-li">
<a id="active" href="home.html">Home</a>
</li>
<li class="submenu1-li">
About
</li>
<li id="desktop-contact-move" class="submenu1-li" >
Contact
</li>
<li id="desktop-port-move" class="submenu1-li" style:"order: 1;">
<a href="javascript:void(0)" onclick="myFunction_2();">Portfolio
<span class="arrow">▼</span>
</a>
<ul id="submenu2">
<li class="submenu2-li">
Designs
</li>
<li class="submenu2-li">
Websites
</li>
<li class="submenu2-li">
Photography
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
Ok so here the problem is that the x.style.display returns blank string because that property is defined in stylesheet.
1st solution is to use inline css
2nd is apply another check for blank string like this.
function myFunction() {
var x = document.getElementById("submenu1");
if (x.style.display === "none" || x.style.display === "") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function myFunction_2() {
var y = document.getElementById("submenu2");
if (y.style.display === "none" || y.style.display === "") {
y.style.display = "block";
} else {
y.style.display = "none";
}
}
.main-nav {
display: flex;
}
.main-nav ul {
display: flex;
flex-wrap: wrap;
flex: 1;
list-style: none;
}
.main-nav li {
text-align: center;
position: relative;
width: 100%;
border-bottom: 1px solid white;
}
#submenu1 .submenu1-li:first-of-type {
border-top: 1px solid white;
}
.main-nav a {
display: flex;
display: block;
align-items: center;
justify-content: center;
flex: 1;
color: #fff;
background-color: #000;
padding: 5% 0%;
}
.submenu1-li {
position: absolute;
top: 0px;
}
#submenu1 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
.submenu2-li {
position: absolute;
top: 0px;
}
#submenu2 {
display: none;
flex-direction: column;
position: absolute;
width: 100%;
}
#submenu2 .submenu2-li:first-of-type {
border-top: 1px solid white;
}
#active {
background-color: #ffffff;
color: #000000;
height: 100%;
}
#submenu1 a:hover {
color: black;
background-color: white;
}
#desktop-port-move:hover #submenu2 {
display: block;
}
<nav class="main-nav">
<ul>
<li>
<a id="hide" href="javascript:void(0)" onclick="myFunction()">Menu
<span class="arrow">▼</span>
</a>
<ul id="submenu1">
<li class="submenu1-li">
<a id="active" href="home.html">Home</a>
</li>
<li class="submenu1-li">
About
</li>
<li id="desktop-contact-move" class="submenu1-li" >
Contact
</li>
<li id="desktop-port-move" class="submenu1-li" style:"order: 1;">
<a href="javascript:void(0)" onclick="myFunction_2();">Portfolio
<span class="arrow">▼</span>
</a>
<ul id="submenu2">
<li class="submenu2-li">
Designs
</li>
<li class="submenu2-li">
Websites
</li>
<li class="submenu2-li">
Photography
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
More information about the problem at : Fixing the Mobile Double-Click Link Issue
So here is my little HTML page with a playlist of videos:
http://jsfiddle.net/VvR4H/3/
As you can see, in the grey area I have an inline list of playlists, I have three now:
Kangaroo Fighting
Australian Sports
Real Football
Under each playlist are listed videos.
What I want to achieve is a nice horizontal scrolling between my playlists. Right now, when you click on the left or right corner of the grey playlist bar (where the text is half cut), it will slide to the other playlist.
However the sliding is not very nice. I want the Kangaroo Fighting to slide in the middle of the playlist bar when you click on the left corner, could you help me please?
Here is my HTML:
<div class="container">
<ul class="playlists">
<li class="playlist">
<div class="title"> <span class="move-left">Real Foorball</span>
<span>Kangaroo Fighting</span>
<span class="move-right">Australian Sports</span>
</div>
<ul class="videos">
<li class="video">Video 1 C</li>
<li class="video">Video 2 C</li>
<li class="video">Video 3 C</li>
</ul>
</li>
<li class="playlist">
<div class="title"> <span class="move-left">Kangaroo Fighting</span>
<span>Australian Sports</span>
<span class="move-right">Real Football</span>
</div>
<ul class="videos">
<li class="video">Video 1 A</li>
<li class="video">Video 2 A</li>
<li class="video">Video 3 A</li>
</ul>
</li>
<li class="playlist">
<div class="title"> <span class="move-left">Australian Sports</span>
<span>Real Football</span>
<span class="move-right">Kangaroo Fighting</span>
</div>
<ul class="videos">
<li class="video">Video 1 B</li>
<li class="video">Video 2 B</li>
<li class="video">Video 3 B</li>
</ul>
</li>
</ul>
</div>
My CSS:
ul li {
list-style: none;
}
.container {
position: relative;
background: #000;
width: 300px;
height: 500px;
overflow: hidden;
font-family: sans-serif;
}
ul.playlists {
width: 1200px;
padding-left: 0;
margin-top: 0;
position: absolute;
left: -300px;
}
ul.playlists li {
float: left;
width: 300px;
height: 50px;
}
ul.playlists li.playlist .title {
width: 100%;
background: grey;
color: white;
line-height: 50px;
text-align: center;
}
ul.playlists li.playlist .title .move-left, ul.playlists li.playlist .title .move-right {
width: 30px;
line-height: 50px;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
}
ul.playlists li.playlist .title .move-left {
float: left;
direction: rtl;
}
ul.playlists li.playlist .title .move-right {
float: right;
}
ul.videos {
clear: both;
padding-left: 0;
}
ul.videos li {
float: left;
width: 250px;
height: 50px;
padding: 25px;
color: white;
background: blue;
border-top: 1px solid black;
}
And my JavaScript:
$(".move-left").click(function () {
$(this).parent().parent().parent().animate({
"left": "0"
}, 500, "linear", function () {
console.log("yay");
});
});
$(".move-right").click(function () {
$(this).parent().parent().parent().animate({
"left": "-600"
}, 500, "linear", function () {
console.log("yay");
});
});
It is not complete (I didnt do infinity loop), but I guess it has better animation as you requested.
I separated your html into 2 parts. First one is moving slower then second one. So you can se half text of next titles but you dont have to duplicate texts.
http://jsfiddle.net/VvR4H/10/
html
<div class="container">
<div class="title-wrapper">
<div class="title">
<span>Real Foorball</span>
<span>Kengoroo Fighting</span>
<span>Australian Sports</span>
</div>
</div>
<div class="playlist">
<ul class="videos">
<li class="video">Video 1 C</li>
<li class="video">Video 2 C</li>
<li class="video">Video 3 C</li>
</ul>
<ul class="videos">
<li class="video">Video 1 A</li>
<li class="video">Video 2 A</li>
<li class="video">Video 3 A</li>
</ul>
<ul class="videos">
<li class="video">Video 1 B</li>
<li class="video">Video 2 B</li>
<li class="video">Video 3 B</li>
</ul>
</div>
</div>
css
ul li {
list-style: none;
}
.container {
position: relative;
background: #000;
width: 300px;
height: 500px;
font-family: sans-serif;
overflow: hidden;
}
div.title-wrapper {
background: grey;
height: 50px;
}
div.title {
position: absolute;
overflow: hidden;
height: 50px;
left: 75px;
white-space: nowrap;
}
div.playlist {
position: absolute;
overflow: hidden;
top: 50px;
clear: both;
white-space: nowrap;
}
div.title span {
width: 300px;
background: grey;
color: white;
line-height: 50px;
text-align: left;
display: block;
float: left;
margin: 0;
padding: 0;
text-indent: 20px;
}
ul.videos {
float: left;
width: 300px;
margin: 0;
padding: 0;
}
ul.videos li {
display: block;
background: blue;
height: 50px;
padding: 10px 20px;
margin: 1px 0 0 0;
color: white;
}
javascript
$('.title span').css({
'text-indent' : '0',
'text-align' : 'center',
'width' : '150px'
});
var titles = [];
$('.title span').each( function () {
titles.push($(this));
});
var max = titles.length-1;
var left = max;
var right = 1;
$('.title span').click(function () {
console.log($(this).context.innerText + ' left: ' +titles[left].context.innerText + ' right: ' +titles[right].context.innerText)
if($(this).context==titles[left].context) {
left = (left==0) ? max : --left;
right = (right==0) ? max : --right;
$('.title').animate({
"left": "+=150px"
}, 500);
$('.playlist').animate({
"left": "+=300px"
}, 500);
}
if($(this).context==titles[right].context) {
left = (left==max) ? 0 : ++left;
right = (right==max) ? 0 : ++right;
$('.title').animate({
"left": "-=150px"
}, 500);
$('.playlist').animate({
"left": "-=300px"
}, 500);
}
});