CSS Flyout Menu in conjunction with scrolling menu - javascript

I am new to javascript and am having trouble with menus. I can get a flyout menu to work, and I can get a scrolling menu to work (demo of scrolling menu http://css-tricks.com/examples/LongDropdowns/).
However, I cannot figure out how to merge the effects. Can someone please help me with the flyout code for below?
//HTML
<ul class="dropdown">
<li>CITIES BY STATE
<ul>
for (var p = 0; p < state.length; p++) {
<li> + states[p][0] + "");
<ul id="city\" class="city">
<li>CITY 1</li>
<li>CITY 2</li>
<li>CITY 3</li>
</ul>");
</li>");
}
</ul>
</ul>
</li>
//SCRIPT TO ALLOW SCROLL THROUGH LIST
<script>
var maxHeight = 600;
$(function(){
$(".dropdown > li").hover(function() {
var $container = $(this),
$list = $container.find("ul"),
$anchor = $container.find("a"),
height = $list.height() * 1.1, // make sure there is enough room at the bottom
multiplier = height / maxHeight; // needs to move faster if list is taller
// need to save height here so it can revert on mouseout
$container.data("origHeight", $container.height());
// so it can retain it's rollover color all the while the dropdown is open
$anchor.addClass("hover");
// don't do any animation if list shorter than max
if (multiplier > 1) {
$container
.css({
height: maxHeight,
overflow: "hidden"
})
.mousemove(function(e) {
var offset = $container.offset();
var relativeY = ((e.pageY - offset.top) * multiplier) - ($container.data("origHeight") * multiplier);
if (relativeY > $container.data("origHeight")) {
$list.css("top", -relativeY + $container.data("origHeight"));
};
});
}
}, function() {
var $el = $(this);
// put things back to normal
$el
.height($(this).data("origHeight"))
.find("ul")
.css({ top: 0 })
.show()
.find("a")
.removeClass("hover");
});
});
</script>
This is what I have tried, but I am off. I want a list of cities to display to the right of the state list when I hover on a state.
/*code to show/hide city menu*/
#city li:hover ul ul, #city li:hover ul ul ul, #city li:hover ul ul ul ul{
display:none;
}
#city li:hover ul, #city li li:hover ul, #city li li li:hover ul, #city li li li li:hover ul{
display:block;
}

Chrisoph is right. This is just jibberish:
<ul class="dropdown">
<li>CITIES BY STATE
<ul>
for (var p = 0; p < state.length; p++) {
<li> + states[p][0] + "");
<ul id="city\" class="city">
<li>CITY 1</li>
<li>CITY 2</li>
<li>CITY 3</li>
</ul>");
</li>");
}
</ul>
</ul>
</li>
This is syntactially correct HTML/Javascript. Screw it... I decided to just code it for you because I'm bored, but you really need to go back to basics in HTML/JavaScript.
<html>
<head>
<title>test</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function()
{
var map = [
{state: "NSW", cities: ["Sydney", "Newcastle", "Orange"]},
{state: "QLD", cities: ["Brisbane", "Cairns", "Townsville"]},
{state: "VIC", cities: ["Melbourne", "Geelong", "Ballarat"]},
{state: "SA", cities: ["Radelaide", "Mount Gambier"]},
{state: "TAS", cities: ["Hobart", "Devonport", "Launceston"]}
];
for (var i = 0; i < map.length; i++)
{
var a = $('<a href="#">').html(map[i].state);
var li = $('<li>').append(a);
var cities = $('<ul>').attr('id', map[i].state).addClass('cityList');
for(var j = 0; j < map[i].cities.length; j++)
{
cities.append($('<li>').html(map[i].cities[j]));
}
li.append(cities);
$('#citiesByState').append(li);
}
});
</script>
</head>
<body>
<ul class="dropdown">
<li>
CITIES BY STATE
<ul id="citiesByState"></ul>
</li>
</ul>
</body>
</html>
Now go back and fix your question and test it then we'll look at any new problems.

Related

Active Navigation On Scroll anchor links

I've been trying to figure this out for hours. I currently have a fixed nav for my anchor website. I would like the menu link background color to change when scrolling through each section. Like this: https://codepen.io/dbilanoski/pen/LabpzG . When I scroll through each section I only see the hover background color not the active state color. If you have any tips or advice, please advise.
Thank you!
var navLink = $(".nav-link"),
topMenuHeight = navLink.outerHeight() + 15,
//All list items
menuItems = navLink.find("a"),
//Anchors corresponding to menu items
scrollItems = menuItems.map(function() {
var item = $($(this).attr("href"));
if (item.length) {
return item;
}
});
// Bind click handler to menu items
// so we can get a fancy scroll animation
menuItems.click(function(e) {
var href = $(this).attr("href")
offsetTop = href === "#" ? 0 : $(href).offset().top - topMenuHeight + 1;
$('html, body').stop().animate({
scrollTop: offsetTop
}, 300);
e.preventDefault();
});
// 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 : "";
if (navLink !== id) {
navLink = id;
// Set/remove active class
menuItems
.parent().removeClass("active")
.end().filter("[href='#" + id + "']").parent().addClass("active");
}
});
a {
color: inherit;
text-decoration: none;
}
a:hover {
color: #fa448c;
text-decoration: underline;
}
a:active {
background-color: #fa448c;
color: #fff;
}
li {
list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu">
<ul class="nav-list">
<li class="nav-item">
Home
</li>
<li class="nav-item">
Products
</li>
<li class="nav-item">
Featured
</li>
<li class="nav-item">
Best Sellers
</li>
<li class="nav-item">
Contact
</li>
</ul>
</div>
The trick of the codepen you've sent is that all sections have the same height. However, there's a more flexible way of doing that. Using this solution, you check for each section whether it's shown on the screen or not, and if it is, highlight its button in the navlist.

Dropdown Menu Closes On Hover (Error)

Whhenever I hover over the menu it works fine. But, when I try to get to the submenu links and children, the menu closes
/*----------------------------------------------------
/* Dropdown menu
/* ------------------------------------------------- */
jQuery(document).ready(function($) {
function mtsDropdownMenu() {
var wWidth = $(window).width();
if (wWidth > 865) {
$('#navigation ul.sub-menu, #navigation ul.children').hide();
var timer;
var delay = 100;
$('#navigation li').hover(
function() {
var $this = $(this);
timer = setTimeout(function() {
$this.children('ul.sub-menu, ul.children').slideDown('fast');
}, delay);
},
function() {
$(this).children('ul.sub-menu, ul.children').hide();
clearTimeout(timer);
}
);
} else {
$('#navigation li').unbind('hover');
$('#navigation li.active > ul.sub-menu, #navigation li.active > ul.children').show();
}
}
mtsDropdownMenu();
$(window).resize(function() {
mtsDropdownMenu();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="menu-item-513" class="menu-item "><i class="fa fa-calculator"></i> OFFERTE AANVRAGEN
<ul class="sub-menu">
<li id="menu-item-1146" class="menu-item">Zonnepanelen installatie (Belgiƫ)
</li>
<li id="menu-item-1144" class="menu-item">Zonnepanelen reinigen (Belgiƫ)
</li>
<li id="menu-item-1145" class="menu-item">Zonnepanelen installatie (Nederland)
</li>
</ul>
</li>
The code you posted works just fine; here's a plnkr to prove it: https://plnkr.co/edit/IFaueUhKE3J1K9vY1NkQ?p=preview
(simply wrapped a <div id='navigation'><ul> round the top li).
If you still loose the hover over the child-elements, it's caused by something you're not showing in the original question. E.g. adding this css:
li.menu-item {
position: relative;
top: 50px;
left: 300px;
}
would make it difficult to reach the child items because you, briefly, lose the parent-hover while moving to the child.

how to make li (active) and visible on click of its parent li

helo , i just wanted to make my li child visibile on the click of parent li,if you want to check what i want to make check out http://technologyvs.co.uk
go to the what client say section
var selector, elems, makeactive,//this is for li one
childSelector,childElems , makeChildActive;//this is for li two
selector = ".parent li";
elems = document.querySelectorAll(selector);
makeactive = function () {
for (var i = 0; i < elems.length; i++) {
elems[i].classList.remove('active');
this.classList.add('active');
}
}
for (var i = 0; i < elems.length; i++) {
elems[i].addEventListener("mousedown", makeactive);
}
childSelector = ".child li"
childElems = document.querySelectorAll(childSelector);
makeChildActive = function (){
for (var j=0;j<childElems.length;j++){
childElems[j].classList.remove('child-active');
this.classList.add('child-active');
}
}
for(var j=0; j<childElems.length;j++){
childElems[j].addEventListener("mousedown",makeChildActive);
}
li.active{
color: red;
}
.text li{
visibility:visible;
transition: all 1s ease-in-out;
}
li.child-active{
visibility: hidden;
width: 200px;
margin-left: 25px;
font-size: 25px;
}
<!Doctype html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="custom.css" type="text/css">
</head>
<body>
<h1>heloo</h1>
<ul class="parent">
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
<ul class="child">
<li>text1</li>
<li>text2</li>
<li>text3</li>
<li>text4</li>
</ul>
<script src="custom.js"></script>
</body>
</html>
Heres the simple code to do it, there are probably some edge-cases that I am not looking at but in essence this will do the trick. I added the code to a modified version of yours in the snippet below so you can see it works. I have taken out all the code that was not necessary to show how this works.
// A handler that allows us to remember the 'i' value when executing the click
function eventHandlerClosure(i){
parents[i].addEventListener('click', function(e){
// disable the currently active one
var active = document.querySelector('.child li.active');
// (if there is one)
if(active) active.className = '';
// add the active class to the newly selected child
if(children[i]) children[i].className = 'active';
}, false);
}
// select all parents and children
var parents = document.querySelectorAll('.parent li');
var children = document.querySelectorAll('.child li');
// attach the click events
for(var i = 0; i < parents.length; i++) eventHandlerClosure(i);
function eventHandlerClosure(i){
parents[i].addEventListener('click', function(e){
var active = document.querySelector('.child li.active');
if(active) active.className = '';
children[i].className = 'active';
}, false);
}
var parents = document.querySelectorAll('.parent li');
var children = document.querySelectorAll('.child li');
for(var i = 0; i < parents.length; i++) eventHandlerClosure(i);
.child li { visibility: hidden; }
.child li.active { color: red; visibility: visible; }
<ul class="parent">
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
<ul class="child">
<li>text1</li>
<li>text2</li>
<li>text3</li>
<li>text4</li>
</ul>

JS Dropdown Menu Behavior

I have a dropdown menu working but I can't figure out how to close the previous menu onclick. All the menues stay open so I need them to close when a different menu is open.
Please see my jsfiddle
https://jsfiddle.net/yvhnphp4/
$(document).ready(function(){
// Dropdown menu
var findDropdowns = document.querySelectorAll(".has-dropdown");
for(var i = 0; i < findDropdowns.length; i++) {
if(i == 0) {
var dropdownId = "has-dropdown-1";
findDropdowns[i].setAttribute("id", dropdownId);
}else {
var addOneToIndex = i + 1;
dropdownId = "has-dropdown-" + addOneToIndex;
findDropdowns[i].setAttribute("id", dropdownId);
}
var targetDropdown = document.getElementById(dropdownId);
targetDropdown.onclick = dropdownTrigger;
}
function dropdownTrigger(e) {
e.preventDefault();
var showHideDropdown = e.target.nextElementSibling;
showHideDropdown.setAttribute("class", "show");
}
});
<ul class="nav">
<li><a class="has-dropdown" href="">Link</a>
<ul>
<li>Sub-Link</li>
<li>Sub-Link</li>
<li>Sub-Link</li>
</ul>
</li>
<li><a class="has-dropdown" href="">Link</a>
<ul>
<li>Sub-Link</li>
<li>Sub-Link</li>
<li>Sub-Link</li>
</ul>
</li>
</ul>
.nav ul {display:none;}
.nav ul.show{display:block;}
You can simply remove the .show class from all ul tags in .nav that still have it, before opening a new dropdown:
function dropdownTrigger(e) {
var opened = document.querySelectorAll(".nav ul.show");
for(var i = 0; i < opened.length; i++) {
opened[i].removeAttribute("class");
}
...
}
Note that since you're using jQuery anyway ($(document).ready) there is probably a much better way to do this.
Also, use href="#" instead of href="".

why doesn't this drop-down menu work with mouseover and leave?

I want it to display "you" under "Home" when hovering and disappearing when mouse leaving:
// HTML
<ul>
<li><a id="homeBox" href="#">Home</a>
<ul><li><a id="homeSub" href="#">you</a></li></ul>
</li>
</ul>
// javaScript
var homeB= document.getElementById("homeBox");
var homeS = document.getElementById("homeSub")
homeBox.mouseover = function() {
var homeS = document.getElementById("homeSub").style.display= "block";
}
homeBox.mouseleave = function() {
var homeS = document.getElementById("homeSub").style.display= "none";
}
// CSS
<style>
ul li ul li a #homeSub {display: hidden;}
</style>
Why Javascript? Use simple CSS Solution.
ul li ul{display: none;}
ul li:hover ul{display: block;}
DEMO
There were quite a few issues. If you have any questions let me know
homeBox.mouseover
There is no homeBox use homeB, and mouseover isnt an event handler onmouseover is.
homeB.onmouseover
ul li ul li a #homeSub {display: hidden;}
This is looking for a link with a child that has the id homeSub, and display: hidden should be display: none
ul li ul li a#homeSub {display: none;}
var homeS = document.getElementById("homeSub").style.display= "block";
You've already defined homeS
homeS.style.display = 'block';
var homeB = document.getElementById("homeBox");
var homeS = document.getElementById("homeSub");
homeB.onmouseover = function() {
homeS.style.display = "block";
}
homeB.onmouseout = function() {
homeS.style.display = "none";
}
ul li ul li a#homeSub {
display: none;
}
<ul>
<li><a id="homeBox" href="#">Home</a>
<ul><li><a id="homeSub" href="#">you</a></li></ul>
</li>
</ul>
You don't need any javascript for this functionality. Just use CSS - http://jsfiddle.net/akq1e5o6/
P.S.: there is no avaliable hidden value for display property
<ul>
<li><a id="homeBox" href="#">Home</a>
<ul><li><a id="homeSub" href="#">you</a></li></ul>
</li>
</ul>
-Use onmouseover instead of mouseover
-Put your Javascript between script-tags, and in a function that will execute after the page has loaded (and use 'none' instead of 'hidden').
<script>
(function() {
var homeB= document.getElementById("homeBox");
var homeS = document.getElementById("homeSub");
homeB.onmouseover = function() {
homeS.style.display = "block";
}
homeB.onmouseleave = function() {
homeS.style.display= "none";
}
})();
</script>
-And adjust your stylesheet:
<style>
#homeSub {display: none;}
</style>

Categories