jQuery expandable menu - javascript

<div id="firstDiv">
<div id="secondDiv">
<ul id="accordionMenu">
<li>menu item</li>
<li>menu item
<ul>
<li>suboption 1</li>
<li>suboption 2</li>
</ul>
</li>
<li>menu item</li>
<li>menu item</li>
<li>menu item</li>
</ul>
</div>
</div>
How to make it expandable?
I have the following JavaScript code:
$(document).ready(function() {
// Collapse everything but the first menu:
$("#accordionMenu > li > a").not(":first").find("+ ul").slideUp(1);
// Expand or collapse:
$("#accordionMenu > li > a").click(function() {
$(this).find("+ ul").slideToggle("fast");
});
});

#Yoshi: Thank you. I'll add the answer here, hope will help others
HTML
<div id="firstDiv">
<div id="secondDiv">
<ul id="accordionMenu">
<li>menu item</li>
<li>menu item
<ul>
<li>suboption 1</li>
<li>suboption 2</li>
</ul>
</li>
<li>menu item</li>
<li>menu item</li>
<li>menu item</li>
</ul>
</div>
</div>
jQuery:
// Collapse everything but the first menu:
$("#accordionMenu > li > a").not(":first").find("+ ul").slideUp(1);
// Expand or collapse:
$("#accordionMenu > li > a").click(function() {
$(this).find("+ ul").slideToggle("fast");
});​
Don't forget to include jQuery library :)

Related

Load content on anchor link click

I have content that is hidden by default. On button click, I want the selected one to show its content. I.e if find more is clicked on the second div, show the content for that div.
Approach so far:
function showClass(a) {
var e = [];
var e = document.getElementsByClassName(a);
for (elem of e) {
if (!elem) return true;
if (elem.style.display == "none") {
elem.style.display = "block"
} else {
elem.style.display = "none"
}
}
return true;
}
.list {
display: none;
}
a {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list">
<ul>
<li>list 1</li>
<li>list 2</li>
<li>list 3</li>
</ul>
</div>
<div class="list">
<ul>
<li>list 4</li>
<li>list 5</li>
<li>list 6</li>
</ul>
</div>
<div class="list">
<ul>
<li>list 7</li>
<li>list 8</li>
<li>list 9</li>
</ul>
</div>
<a onclick="showClass('list');" class="loadMoreBtn">Find out more</a>
Where am I going wrong?
You have a few issues:
You should use document.getElementsByClassName(a); (note the document)
To iterate through a HTMLCollection (returned by getElementsByClassName) you should use .forEach, for...of or a regular for loop. for...in is not a recommended way to iterate a collection as it is made to iterate over properties in an object. Thus, the for..in loop can give unexpected properties of the HTMLCollection such as its length when using it to iterate (when instead all you're after is the node)
function showClass(a) {
// var e = []; <-- no need for this \/ redeclared below
var e = document.getElementsByClassName(a);
for (elem of e) {
if (!elem) return true;
if (elem.style.display == "none") {
elem.style.display = "block"
} else {
elem.style.display = "none"
}
}
return true;
}
.list {
display: none;
}
a {
cursor: pointer;
}
<div>
<ul class="list">
<p>sample text</p>
<li>list 1</li>
<li>list 2</li>
<li>list 3</li>
</ul>
</div>
<div>
<ul class="list">
<li>list 4</li>
<li>list 5</li>
<li>list 6</li>
</ul>
</div>
<div>
<ul class="list">
<p>sample text</p>
<li>list 7</li>
<li>list 8</li>
<li>list 9</li>
</ul>
</div>
<a onclick="showClass('list');" class="loadMoreBtn">Find out more</a>
To have separate buttons for each item/div you can give each item an id, and then toggle the id by passing it through as an argument:
function showClass(id) {
var elem = document.getElementById(id);
var visible = getComputedStyle(elem).display == "block";
if (!visible) {
elem.style.display = "block"
} else {
elem.style.display = "none"
}
}
.list {
display: none;
}
a {
cursor: pointer;
}
<div>
<ul class="list" id="list-one">
<li>list 1</li>
<li>list 2</li>
<li>list 3</li>
</ul>
</div>
<div>
<ul class="list" id="list-two">
<li>list 4</li>
<li>list 5</li>
<li>list 6</li>
</ul>
</div>
<div>
<ul class="list" id="list-three">
<li>list 7</li>
<li>list 8</li>
<li>list 9</li>
</ul>
</div>
<a onclick="showClass('list-one');" class="loadMoreBtn">Find out more - Item 1</a>
<br />
<a onclick="showClass('list-two');" class="loadMoreBtn">Find out more - Item 2</a>
<br />
<a onclick="showClass('list-three');" class="loadMoreBtn">Find out more - Item 3</a>
Since you've tagged the question with jQuery and you're including it, you should really use it for this since it's very simple, concise and readable code...
function toggleClass(className) {
$("." + className).toggle();
}
.list {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script>
<div>
<ul class="list">
<p>sample text</p>
<li>list 1</li>
<li>list 2</li>
<li>list 3</li>
</ul>
</div>
<div>
<ul class="list">
<li>list 4</li>
<li>list 5</li>
<li>list 6</li>
</ul>
</div>
<div>
<ul class="list">
<p>sample text</p>
<li>list 7</li>
<li>list 8</li>
<li>list 9</li>
</ul>
</div>
<a onclick="toggleClass('list');" class="loadMoreBtn">Find out more</a>
As you can see, jQuery has a toggle() method that toggles visibility, and jQuery methods work on arrays of elements by default, so you don't need a loop and you don't need to check the current visible state of anything.
You could also go a bit further and assign the event handler in Javascript, rather than inline in the anchor element, like this...
$(".loadMoreBtn").on("click", function() {
$(".list").toggle();
});
Keeping your Javascript out of HTML is encouraged, as it means you don't have to hunt different files to find it, which is great for both you and anyone else that ever has to look at your code.
Please have look at below code i have madden few changes in your code
function showClass(a) {
var e = [];
var e = document.getElementsByClassName(a);
console.log(e);
for (i=0;i<=e.length;i++) {
if (!e[i]) return true;
e[i].classList.add("displayblock");
}
return true;
}
function removeClass(a) {
var e = [];
var e = document.getElementsByClassName(a);
console.log(e);
for (i=0;i<= e.length;i++) {
if (!e[i]) return true;
e[i].classList.remove("displayblock");
}
return true;
}
Styles
.list {
display: none;
}
a {
cursor: pointer;
}
.displayblock{
display: block;
}
HTML
<div>
<ul class="list">
<p>sample text</p>
<li>list 1</li>
<li>list 2</li>
<li>list 3</li>
</ul>
</div>
<div>
<ul class="list">
<li>list 4</li>
<li>list 5</li>
<li>list 6</li>
</ul>
</div>
<div>
<ul class="list">
<p>sample text</p>
<li>list 7</li>
<li>list 8</li>
<li>list 9</li>
</ul>
</div>
<a onclick="showClass('list');">Find out more</a>
<a onclick="removeClass('list');">Hide more</a>
Share your improve reference
Read the error messsage,
Uncaught ReferenceError: getElementsByClassName is not defined
The actual method you are looking for is window.document.getElementsByClassName

Searching for formula to align submenus direction in menu along the width

Currently I'm trying to achieve this
With this: http://jsfiddle.net/EJXNV/3/
HTML:
<div>
<ul>
<li>Menu
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</li>
<li>Menu
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</li>
<li>Menu
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</li>
<li>Menu
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</li>
<li>Menu
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</li>
<li>Menu
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</li>
JS:
var coef = 7.5;
$("div > ul > li").each(function () {
$(this).children("ul").css("left",
($(this).position().left
/ coef)
* (-1));
});
But I can't figure out from where I should took that coefficient = 7.5 (I've got it empirically).
Please, help me to find out what formula I should use to get this coefficient.
I was able to figure out it by myself:
$("div > ul > li").each(function () {
var coef = $("div > ul > li").last().position().left / ($(this).children("ul").width() - $(this).width());
$(this).children("ul").css("left", ($(this).position().left / coef) * (-1));
});
http://jsfiddle.net/EJXNV/4/
Works with any width of any element (except the container, it must be fixed width and relative).

How to make submenu for jQuery sliding side menu?

Is there a way to make submenu for sliding side menu?
JS Fiddle demo
<ul id="nav">
<li>Menu Item 1</li>
<ul id="submenu">
<li>Submenu Item 1</li>
<li>Submenu Item 2</li>
</ul>
<li>Menu Item 2</li>
</ul>
Fiddle DEMO
Changed Markup
added ul instead of li as ul can not directly contain ul
<div id="menu">
<ul>
<li>Menu Item 1
<ul id="submenu"> <!-- added ul instead of li -->
<li>Submenu Item 1
</li>
<li>Submenu Item 2
</li>
</ul>
</li>
<li>Menu Item 2
</li>
<li>Menu Item 3
</li>
</ul>
</div>
<div id="right">
<button type="button" id="button">Menu</button>
</div>
JS
$('#menu li:has("ul")').children('ul').hide(); //hide submenu
$('#button').toggle(
function () {
$('#right').animate({
left: 150
});
},
function () {
$('#right').animate({
left: 0
});
});
$('#menu li:has("ul")').click(function(){
$(this).children('ul').slideToggle(); //toggle submenu
});
References
.slideToggle()
:has()

onclick one menu should be open in jquery

i want that on click of a main link its sublinks open when i click on any other main link its sublinks open and previous opened closes .at a time only one menu should be open.here is the fiddle http://jsfiddle.net/ZCrk4/6/
<!-- Wrapper -->
<div id="wrapper">
<!-- Container -->
<div id="container" class="resolution_800x600">
<!-- Colonnage -->
<div id="colonnes" class="clear">
<!-- Navigation Level 02 -->
<div id="nav1" class="navigation_02">
<ul>
<li>Menu 1
<ul>
<li>Sub menu 1</li>
<li>Sub menu 2</li>
<li>Sub menu 3</li>
</ul>
</li>
<li>Menu 2
<ul>
<li>Sub menu 1</li>
<li>Sub menu 2</li>
</ul>
</li>
<li>Menu 3
<ul>
<li>Sub menu 1</li>
<li>Sub menu 2</li>
<li>Sub menu 3</li>
<li>Sub menu 4</li>
</ul>
</li>
<li>Menu 4
<ul>
<li>Sub menu 1</li>
<li>Sub menu 2</li>
<li>Sub menu 3</li>
</ul>
</li>
</ul>
</div>
<!-- /Navigation Level 02 -->
</div>
<!-- /Colonnage -->
</div>
<!-- /Container -->
</div>
<!-- /Wrapper -->
DEMO
var nav = $('#nav1 > ul > li');
nav.find('li').hide();
nav.click(function () {
nav.not(this).find('li').hide();
$(this).find('li').slideToggle();
});
or
DEMO
var nav = $('#nav1 > ul > li');
nav.children('ul').children('li').hide();
nav.click(function () {
nav.children('ul').children('li').hide();
$(this).children('ul').children('li').show();
});
Like this?
JS:
$('.navigation_02 li:has("ul") > a').on('click', function (e) {
var $this = $(this);
$('.navigation_02 a.active').not($this).removeClass('active').next().stop(true, true).slideUp('slow');
$this.addClass('active').next().stop(true, true).slideToggle('slow');
});
CSS:
.navigation_02 > ul > li ul {
display:none;
}
.active{
font-style:bold;
background-color:#cecece;
}
Demo

Is there anyway to stop collapsible side navigation to stop jumping on page load?

The code works except it keeps jumping every time I load or refresh the page and I was wondering if anyone knows of a good solution to this? Any help much appreciated.
Press the 'Run' button on this Jsfiddle to see what I mean.
<div id="sideNav_header">Navigation</div>
<ul id="collapsibleMenu">
<li>Link
<ul>
<li>Link</li>
<li>Link</li>
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 2.1</li>
<li>List Item 2.2</li>
<li>List Item 2.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 3.1</li>
<li>List Item 3.2</li>
<li>List Item 3.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 4.1</li>
<li>List Item 4.2</li>
<li>List Item 4.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 5.1</li>
<li>List Item 5.2</li>
<li>List Item 5.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 1.1</li>
<li>List Item 1.2</li>
<li>List Item 1.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 2.1</li>
<li>List Item 2.2</li>
<li>List Item 2.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 3.1</li>
<li>List Item 3.2</li>
<li>List Item 3.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 4.1</li>
<li>List Item 4.2</li>
<li>List Item 4.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 5.1</li>
<li>List Item 5.2</li>
<li>List Item 5.3</li>
</ul>
</li>
<li>Link
<ul>
<li>List Item 5.1</li>
<li>List Item 5.2</li>
<li>List Item 5.3</li>
</ul>
</li>
</ul>
//Script//
$("#collapsibleMenu > li > a").find("+ ul").slideUp(1);
// Expand or collapse:
$("#collapsibleMenu > li > a").click(function() {
$(this).find("+ ul").slideToggle("slow");
});​
Yes, change:
$("#collapsibleMenu > li > a").find("+ ul").slideUp(1);
to:
$("#collapsibleMenu > li > a").find("+ ul").slideUp(0);
http://jsfiddle.net/DjbeK/1/
Using slideUp(1) on page load doesn't make sense you can use hide() instead.

Categories

Resources