Javascript for simple menu expanding - javascript

Hi I'm new to JavaScript and I want to code a very simple expanding submenu.
<div id="submenu">
<ul>
<li>
Something
</li>
<li>
Another
</li>
</ul>
<div id="submenu-1" class="submenu-options">
<ul>
<li>Something-sub</li>
<li>Something-sub</li>
<li>Something-sub</li>
</ul>
</div>
<div id="submenu-2" class="submenu-options">
<ul>
<li>Another-sub</li>
<li>Another-sub</li>
<li>Another-sub</li>
</ul>
</div>
</div>
To be more specific, if I hover over something I want the something submenu displayed if the mouse leaves I want it to be hidden again...
I know it has been asked a lot and there are many ways to do this but Google brought up too many unsatisfying answers.
I hope you can spare 10 minutes to help me out of my misery
Regards and thank you!

<div id="submenu">
<ul>
<li id="1">
Something
</li>
<li id="2">
Another
</li>
</ul>
<div id="submenu-1" class="submenu-options">
<ul>
<li>Something-sub</li>
<li>Something-sub</li>
<li>Something-sub</li>
</ul>
</div>
<div id="submenu-2" class="submenu-options">
<ul>
<li>Another-sub</li>
<li>Another-sub</li>
<li>Another-sub</li>
</ul>
</div>
</div>
if you are not using any library then you need to bind it something like this:
var menuText;
window.onload = function()
{
menuText= document.getElementById("1");
menuText.onfocus = menuFocusHandler;
menuText.onblur = menuBlurHandler;
}
function menuFocusHandler()
{
document.getElementById("submenu-1").style.display="inline";
}
function menuBlurHandler()
{
document.getElementById("submenu-1").style.display="none";
}
or you can do this nicely and easily using certain javascript libraries that have APIs to do this easily.. some of these libraries are Jquery (the most popular one), Sencha etc.
Some of these libraries have extensions that have menu implementation etc.

I have used Dojo for things like this with great success. Perhaps the Menu or MenuBar will be of use to you.

You can do this sort of thing easily with jQuery, take this drop down example:
HTML:
<ul>
<li>Nav Item 1</li>
<li class="dropdown">
Nav Item 2
<ul style="display:none">
<li>Sub Menu Item 1</li>
<li>Sub Menu Item 2</li>
<li>Sub Menu Item 3</li>
</ul>
</li>
<li>Nav Item 3</li>
</ul>
jQuery:
$('.dropdown').hover(function() {
$('ul', $(this)).show();
}, function() {
$('ul', $(this)).hide();
});

You do not need java for this just plain CSS will do:
li#submenu:hover div {
display: block;
}

Related

How to fix Slimmenu multi level sub items going out of the screen

I am using slimmenu for my website. but unfortunately submenu is going out of my desktop screen if there have nested child items. So i tried to add a class "edge" with'ul' when it will go out of screen.
Here is the screenshot of the preview where i used the code https://codepen.io/themeix/pen/gyxGNO
But my code doesn't work. Here is my HTML code.
<div class="main-menu-area">
<div class="logo-area">
<h1>My Logo </h1>
</div>
<div class="menu-warpper">
<div class="navigation-navbar">
<ul id="navigation" class="slimmenu">
<li>Main Item</li>
<li>Main Item</li>
<li>Main Item</li>
<li>Main Item</li>
<li>
Main Item
<ul>
<li>
Sub Menu 1
<ul>
<li>
Sub Menu 2
<ul>
<li>
Sub Menu 3
<ul>
<li>
Sub Menu 4
<ul>
<li>
Sub Menu 5
<ul>
<li>Sub Menu 6</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Sub Menu 1</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
I tried the following js code to inject a class edge but unfortunately its adding for all the ul when sub menu items going out of the screen.. I want to inject only for the specific ($this) submenu item when it goes out of the screen.
jQuery(".slimmenu li").on('mouseenter mouseleave', function(e) {
if (jQuery('ul', this).length) {
var elm = jQuery('ul:first', this);
var off = elm.offset();
var l = off.left;
var w = elm.width();
var docH = jQuery(".navigation-navbar").height();
var docW = jQuery(".navigation-navbar").width();
var isEntirelyVisible = (l + w <= docW);
if (!isEntirelyVisible) {
jQuery(this).addClass('edge');
} else {
jQuery(this).removeClass('edge');
}
}
});
in that js code edge class adding for all the submenu items but i want to inject it only for the current .has-submenu item while mousehove and its going out of the screen. and removeclass also not working when i leave the mouse. Can anyone help me to fix that issue for me by using js?
remove your menu width....there is limited space between the nav link and that's why this was happened.

Add css style to elements of 2 lists on element click

I have 2 lists of elements. When I click on an element of first list (it is a link), I basically need to add css class 'is-active' to that element AND to corresponding item from another list. I think they have to be in separate lists, as they are in two different bootstrap columns for mobile friendliness. I am currently styling elements from first list with:
$(document).ready(function(){
$('.tabs li').click(function(){
$(this).addClass('is-active');
$('.tabs li').not(this).removeClass('is-active');
});
})
Can't select elements from the other list though.. Any ideas how can I achieve this functionality with css, js/jquery?
My html structure currently is like this:
<div class="col-md-6">
<ul class="tabs">
<li class="tabs-title is-active">
title_1
</li>
<li class="tabs-title">
title_2
</li>
</ul>
</div>
<div class="col-md-6">
<div class="tabs-content">
<div class="tabs-panel is-active">
<div class="entry">
<p>content_1</p>
</div>
</div>
<div class="tabs-panel">
<div class="entry">
<p>content_2</p>
</div>
</div>
</div>
</div>
When I click on 2nd link from first column, the 2nd div from second column should get 'is-active' class. Is this possible?
I guess lists do not have corresponding elements right now. What do I need to have the items linked in some way?
Here's an example, since we don't know what your list looks like.
<ul class="tabs">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
<ul class="letters">
<li>item a</li>
<li>item b</li>
<li>item c</li>
</ul>
Also, it's easier to remove all instances of the is-active class and then add it just to the target elements.
$(document).ready(function(){
$('.tabs li').click(function(){
var index = $('.tabs li').index(this);
$('.tabs li, .letters li').removeClass('is-active');
$(this).addClass('is-active');
$('.letters li').each(function(i) {
if (i == index)
$(this).addClass('is-active');
})
});
})
https://jsfiddle.net/fzeauw7a/

javascript horizontal menu click to open

Trying to make javascript horizontal menu, but can't get second button to open its own items, (when i click the second button it opens the items that are for the first button) here is current code:
JavaScript:
$(document).ready(function() {
$(".menu-button,.menu-button1").click(function() {
$(".menu-bar").toggleClass("open");
});
})
HTML:
<ul class="menu">
<li title="home">menu</li>
<li title="pencil">pencil</li>
<li title="about">about</li>
</ul>
<ul class="menu-bar">
<li>Menu0</li>
<li>Home2000</li>
<li>About</li>
<li>Parent</li>
<li>About</li>
</ul>
<ul class="menu-bar">
<li>Menu1</li>
<li>About</li>
</ul>
Before I start my answer, let me explain jQuery a bit.
$(".menu-button,.menu-button1").click(function() {
$(".menu-bar").toggleClass("open");
});
This broken down:
$(".menu-button,.menu-button1").click(function() { -> When any item with class menu-button OR class menu-button1 is clicked
$(".menu-bar").toggleClass("open"); ->Toggle the "open" class for all elements in your page with class menu-bar.
Since you call all the menus instead of the specific one you want, it opens both of them.
So, be more specific by - for starters - using IDs, or unique/identifying classes:
JS:
$(document).ready(function() {
$(".menu-button.home").click(function() {
$(".menu-bar.home").toggleClass("open");
});
$(".menu-button.pencil").click(function() {
$(".menu-bar.pencil").toggleClass("open");
});
})
HTML:
<ul class="menu">
<li title="home">menu</li>
<li title="pencil">pencil</li>
<li title="about">about</li>
</ul>
<ul class="menu-bar home">
<li>Menu0</li>
<li>Home2000</li>
<li>About</li>
<li>Parent</li>
<li>About</li>
</ul>
<ul class="menu-bar pencil">
<li>Menu1</li>
<li>About</li>
</ul>
I agree with M.Doye's comment about using .each (but sorry, I can't answer directly).
I want to add that, it will be much easier with that kind of HTML structure I think:
<ul class="menu">
<li title="home">
Show Menu 1
<ul class="menu-bar">
<li>Menu1
</li>
</ul>
</li>
<li title="pencil">
Show Menu 2
<ul class="menu-bar">
<li>Menu2
</li>
</ul>
</li>
</ul>
The, click on the link and use .next() or .siblings or closest... to show the right ul.
But of course you'll have to rewrite you CSS :)
Here is updated code
$(document).ready(function () {
$(".menu-button,.menu-button1").click(function () {
$(this).siblings(".menu-bar").toggleClass("open");
})
})
<ul class="menu">
<li title="home">menu
<ul class="menu-bar">
<li>Menu1</li>
<li>About</li>
</ul>
</li>
<li title="pencil">pencil
<ul class="menu-bar">
<li>Menu0</li>
<li>Home2000</li>
<li>About</li>
<li>Parent</li>
<li>About</li>
</ul>
</li>
</ul>
here is a jsfiddle

.click() functionality when clicking elements

Basically i want to click on a tab and a drop down menu appears then when you re-click the same tab or any of the others I want it to hide that tab/show the other tab if clicked on the same/other tab.
I tried
$('.click').click(function() {
$(this).find('.sub-nav-list').toggleClass('active');
});
and tried
$('.click').click(function() {
$('.sub-nav-list').removeClass('active');
$(this).find('.sub-nav-list').toggleClass('active');
});
but cant work it out! any insight? Thanks
html:
<nav class="secondary-nav">
<ul class="list clearfix">
<li class="leaders click">Leadership <span class="arrow">></span>
<ul class="sub-nav-list">
<li>Management</li>
<li>Board of Directors</li>
</ul>
</li>
<li class="contact click">Contact Info <span class="arrow">></span>
<ul class="sub-nav-list">
<li>Email Notification</li>
<li>Information Request</li>
</ul>
</li>
<li class="docs click">Documents <span class="arrow">></span>
<ul class="sub-nav-list">
<li>Governance Documents</li>
<li>Press Release</li>
<li>Reports & Presentations</li>
<li>Sec Filings</li>
<li>Frenquently Asked Questions</li>
<li>Tax Information</li>
</ul>
</li>
<li class="research click">Research <span class="arrow">></span>
<ul class="sub-nav-list">
<li>Dividends and Distributions</li>
<li>Stock Information</li>
<li>Analyst Coverage</li>
<li>Market Makers</li>
</ul>
</li>
</ul>
</nav>
I can see at least two possible issues there.
1) sub-nav-list is not a children of click element. If they are on the same level something like that might work:
$('.click').click(function() {
$(this).parent().find('.sub-nav-list').toggleClass('active');
});
2) You have these elements generated dynamically - so you need use on with selector of any parent element that exists before you dynamically generate your sub-menus (let say nav-list):
$(".click").on("click", ".nav-list", function() {
$(this).parent().find('.sub-nav-list').toggleClass('active');
});

show/hide text relevant to a class based on click using jquery

I'm having a list of products displayed. Once the show more is clicked the text within the extras class needs to be displayed, the show more needs to be hidden and show less needs to be visible. The opposite needs to happen when show less is clicked.
I used the below jQuery code and it works but the problem is that it shows/hide add the extra text in every block. I want it to show only the relevant block.
Javascript
$(document).ready(function() {
$('.extras').css("display", "none");
$('.showmore').click(function() {
$(".extras").toggle();
$('.showmore').hide();
$('.less').show();
});
$('.less').click(function() {
$(".extras").toggle();
$('.extras').hide();
$('.showmore').show()
});
});
HTML
<div class="blocks">
<div class="right">
<ul class="options">
<li class="x">Service 1</li>
<li class="y">Service 2</li>
<li class="z">Service 3</li>
<li class="r">Service 4</li>
<li class="k">Service 5</li>
</ul>
<div class="showmore"><a>+ show more</a></div>
</div>
<div class="extras">
<p>test text</p>
<div class="less"><a>- hide</a></div>
</div>
</div>
<div class="blocks">
<div class="right">
<ul class="options">
<li class="x">Service 1</li>
<li class="y">Service 2</li>
<li class="z">Service 3</li>
<li class="r">Service 4</li>
<li class="k">Service 5</li>
</ul>
<div class="showmore"><a>+ show more</a></div>
</div>
<div class="extras">
<p>test text</p>
<div class="less"><a>- hide</a></div>
</div>
</div>
<div class="blocks">
<div class="right">
<ul class="options">
<li class="x">Service 1</li>
<li class="y">Service 2</li>
<li class="z">Service 3</li>
<li class="r">Service 4</li>
<li class="k">Service 5</li>
</ul>
<div class="showmore"><a>+ show more</a></div>
</div>
<div class="extras">
<p>test text</p>
<div class="less"><a>- hide</a></div>
</div>
</div>
Any help will be appreciated.
Make sure you do your logic in relevant sections. Demo Here
Try:
$(document).ready(function () {
$('.extras').css("display","none");
$('.showmore').click(function () {
var parent = $(this).closest('.blocks');
$(parent).find(".extras").toggle();
$(parent).find('.less').show();
$(this).hide();
});
$('.less').click(function () {
var parent = $(this).closest('.blocks');
$(parent).find(".extras").toggle();
$(parent).find('.showmore').show();
$(this).hide();
});
});
Use .closest()
$(document).ready(function() {
$('.extras').css("display", "none");
$('.showmore').click(function() {
var $div = $(this).closest('.blocks');
$div.find(".extras").toggle();
$div.find('.showmore').hide();
$div.find('.less').show();
});
$('.less').click(function() {
var $div = $(this).closest('.blocks');
$div.find(".extras").toggle();
$div.find(".extras").hide();
$div.find('.showmore').show();
});
});​
Check Fiddle
try using $(this).toggle() in the event handler.
Or I guess more completely, $('.extras').hide(); $(this).show();
Use the $(this) to get the relevant content,
so inside the $(".showmore").click(),
$(this).parents(".blocks").children(".extras").toggle();
$(this).parents(".blocks").children('.showmore').hide();
$(this).parents(".blocks").children('.less').show();
Test Link
You can combine closest, find and toggle to work.
So all your javascript can be changed to the following.
$('.showmore, .less').click(function() {
var $elements = $(this).closest('.blocks').find('.extras, .showmore');
$elements.toggle();
});
demo
References
Closest
Find
Toggle

Categories