Compare link href with address path for menu state - javascript

I'm working on right menu and i want to save that state with compare link href tag with address path location.
function setNavigation() {
var path = window.location.pathname;
path = path.replace(/\/$/, "");
path = decodeURIComponent(path);
$(".sidebar-menu li ul a").each(function () {
var href = $(this).attr('href');
if (path.substring(0, href.length) === href) {
$(this).addClass('active-item');
}
});
The problem is that the code not recognize similar addresses in one ul
for example both of below item give active-item class.
href="site/city/company/"
href="site/city/company/sample"
also here is my html
<li></li>
<li></li>
<li></li>
<li><a href="/Panel/Definitions/Attribute">/a></li>
<li></li>

Correct : $(".sidebar-menu li ul a") to $(".sidebar-menu ul li a")
I have changed the path matching method, check it out:
//sample path
var root_path = "www.xyz.com/";
function setNavigation(path) {
path = path.substring(path.indexOf("/"), path.length);
path = decodeURIComponent(path);
$(".sidebar-menu ul li a").removeClass('active-item');
$(".sidebar-menu ul li a[href='" + path + "']").addClass('active-item');
}
$("a").click(function(e) {
e.preventDefault();
});
$("#navigate").click(function() {
var path = root_path + $("#path").val();
setNavigation(path);
});
$("#navigate").click();
.active-item {
color: #eee;
background-color: #0095ff;
}
ul {
width: 80%;
}
li {
display: block;
margin: 5px;
}
li a {
display: block;
border: 1px solid #888;
padding: 5px;
}
.center {
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="center">
<p>
<b>Path :</b>
www.xyz.com/
<input id="path" value="Panel/Place/item"/>
<input type="button" value="Navigate" id="navigate"/>
</p>
</div>
<div class="sidebar-menu">
<ul>
<li>/Panel/Place</li>
<li>/Panel/Place/item</li>
<li>/Panel/Place/item/City</li>
<li>/Panel/Definitions/Attribute</li>
<li>/Panel/TouristDestination</li>
</ul>
</div>

You can try indexOf method:
if (href.indexOf(path.substring(0, href.length)) !== -1) {
...
Example:
function setNavigation() {
var path = window.location.pathname;
path = path.replace(/\/$/, "");
path = decodeURIComponent(path);
path = '/Panel/Place'; //tmp solution
$(".sidebar-menu li ul a").each(function() {
var href = $(this).attr('href');
if (href.indexOf(path.substring(0, href.length)) !== -1) {
$(this).addClass('active-item');
}
});
}
setNavigation();
.active-item {
color: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="sidebar-menu">
<li>
<ul>
<li>/Panel/Place</li>
<li>/Panel/Place/item</li>
<li>/Panel/Place/City</li>
<li>/Panel/Definitions/Attribute</li>
<li>/Panel/TouristDestination</li>
</ul>
</li>
</ul>

Related

Modify code to take textContent from li instead of thumbnail img src?

I found (and tweaked) the code below that was designed for switching the larger img src with the src of thumbnails in a list, but I'm not sure how to adjust it to use something like https://picsum.photos/id/CLICKED_LI_textContent/200/200 as the URL instead of pulling from a thumbnail's src.
For some more context here's the original post in which I was looking into this
How can I change img src from list of (non-image) items?
I haven't taken any JS classes, so I'm not sure how every component of the script works. I'm more comfortable with pure HTML and CSS, but think JS is the answer for making this work more smoothly.
(I did add the jquery script src to the document for this)
Sorry the code is a little ugly, I would have added the script and style tags and such but I ran out of time while posting this
$("#list li").click(function(e) {
// if i use this getting undefined
// var src = $(this).attr("src");
// so i use this method
var target = e.target;
var src = target.src;
console.log(src);
$("#display").fadeOut(function() {
$(this).on('load', function() {
$(this).fadeIn();
});
$(this).attr("src", src);
});
//record which thumb was clicked
$("#list li").removeClass("active"); //remove class
$(this).addClass("active"); //apply class to selected thumb
});
//move next
$("#left-arrow").click(function() {
if ($("#list li.active").next("#list li").length > 0) {
$("#list li.active").next().children( 'img' ).trigger("click");
} else {
$("#list li:first > img").trigger("click"); //go to first
}
return false;
});
//move previous
$("#right-arrow").click(function() {
if ($("#list li.active").prev("#list li").length > 0) {
$("#list li.active").prev().children( 'img' ).trigger("click");
} else {
$("#list li:last > img").trigger("click"); //go to end
}
return false;
});
//click the first thumb to begin
$("#list li:first > img").trigger("click");
.container {
display: flex;
}
.active {
border-bottom: 1px solid #990000;
}
.list {
width: 200px;
cursor: pointer;
padding: 0.25rem;
}
list > li * {
/* so only the li tag can be event.target, and none of it's children */
pointer-events: none;
}
.display {
max-width: 500px;
max-height: 500px;
}
<div class="container">
<div class="list">
<ul id="list">
<li>237</li>
<li>240</li>
<li>100</li>
<li>301</li>
</ul>
$larr; $rarr;
</div>
<div class="show">
<img src="https://picsum.photos/id/237/200/200" class="display" id="display">
</div>
</div>
Here is a pure javascript solution. The only difference is that it lacks the fading between the images.
I tried to write the code as pedagogic as possible, using variables as explanations. The code goes more with your original thread, where you had a bunch of images with different file endings. I gave the image an alt attribute, so you can see the change.
A short explanation:
Use an array for the images.
Create your list through javascript, using the array.
Add click listeners to your #list, where you read the .textContent. I added pointer-events: none; to any children to the li tags so they don't trigger the click listener.
Add click listeners to your prev/next buttons, where you check which index that the currently visible image has in the array (from 0 to 3 in imageArr) and then adds +1 och -1 to that index.
[edit] Added code for updating the CSS.
const listEl = document.getElementById('list');
const imgElement = document.querySelector('.right > img');
let imageArr = ["237.jpg", "240.gif", "100.jpeg", "301.png"]; // 1
let currentImage = '';
document.getElementById('next').addEventListener('click', () => shiftImage(1));
document.getElementById('prev').addEventListener('click', () => shiftImage(-1));
listEl.addEventListener('click', displayImage);
function updateImage(imageName) {
const subfolder = 'images/';
changeActive(imageName, currentImage); /* ADDED in EDIT */
currentImage = imageName;
imgElement.src = subfolder + imageName;
imgElement.alt = imageName;
}
/* ADDED in EDIT */
function changeActive(newImage, oldImage) {
if (oldImage) {
let oldIndex = imageArr.indexOf(oldImage);
toggleActiveClass(oldIndex);
}
let currentIndex = imageArr.indexOf(newImage);
toggleActiveClass(currentIndex);
}
/* ADDED in EDIT */
function toggleActiveClass(imageIndex) {
let liElements = listEl.childNodes;
liElements[imageIndex].classList.toggle('active');
}
function shiftImage(direction) {
let currentIndex = imageArr.indexOf(currentImage);
let newIndex = currentIndex + direction;
if (newIndex < 0) { newIndex = imageArr.length - 1; }
else if (newIndex >= imageArr.length) { newIndex = 0; }
let newImageName = imageArr[newIndex];
updateImage(newImageName);
}
function displayImage(event) {
let liElement = event.target;
updateImage(liElement.textContent);
}
function constructImageLinks() { // 2
let htmlOutput = '';
for (let imageSrc of imageArr) {
htmlOutput += `<li>${imageSrc}</li>`;
}
listEl.innerHTML = htmlOutput;
}
constructImageLinks();
updateImage(imageArr[0]);
section {
display: flex;
}
section ul {
margin-top: 0px;
}
section > .left li {
cursor: pointer;
padding: 0.25rem;
}
section > .left li.active {
background-color: pink;
}
section > .left li > * {
pointer-events: none;
}
section > div {
padding: 1rem;
}
section > .right > img {
width: 200px;
border: 1px solid;
padding: 0.5rem;
}
<section>
<div class="left">
<ul id="list"></ul>
<button id="prev">Previous</button>
<button id="next">Next</button>
</div>
<div class="right">
<img>
</div>
</section>
JSFiddle - Link
HTML
<div class="container">
<div class="list">
<ul id="list">
<li>237</li>
<li>240</li>
<li>100</li>
<li>301</li>
</ul>
$larr; $rarr;
</div>
<div class="show">
<img src="https://picsum.photos/id/240/200/200" class="display" id="display">
</div>
</div>
Javascript
// HELPER FUNCTIONS
function getImageURL(id, width=200, height=200){
return "https://picsum.photos/id/"+ id + "/" + width + "/" + height;
}
function removeActive(){
let lis = $('#list li');
for(let i=0;i<lis.length;i++){
$(lis[i]).removeClass('active');
}
}
// HANDLE EVENTS
$(document).on('click', "#list li", async (e)=>{
await $('#display').fadeOut();
removeActive();
let li = $(e.target);
li.addClass('active');
let image_id = parseInt($(e.target).html());
let image_url = getImageURL(image_id);
$('#display').attr('src', image_url);
await $('#display').fadeIn();
});
//move next
$(document).on('click', "#left-arrow", (e)=>{
// Handler Here
});
//move previous
$(document).on('click', "#right-arrow", (e)=>{
// Handler Here
});
CSS
.active {
border-bottom: 1px solid #990000;
}
.list {
width: 200px;
cursor: pointer;
padding: 0.25rem;
}
list > li * {
/* so only the li tag can be event.target, and none of it's children */
pointer-events: none;
}
.display {
max-width: 500px;
max-height: 500px;
}
.container {
display: flex;
}

loop through nav menu when li menu's hovered

I am not familar with JavaScript DOM , mostly i use jQuery for script.. I am trying on JavaScript and in trouble with the below code.
Does anyone know what could be the problem?
What i would like to do is when LI is hovered, the nested OL is displayed..somehow, the below code doesn't work, even it doesn't show any error in console.
Please help me...
var ul = document.querySelector('.gnb');
var li = ul.children;
var ol = document.getElementsByTagName('ol');
var i;
for (i = 0; i < li.length; i++) {
li[i].addEventListener('mouseenter', myFunction(myshow));
li[i].addEventListener('mouseleave', myFunction(myhide));
}
function myshow() {
ol.style.display = 'block'
}
function myhide() {
ol.style.display = 'none'
}
function myFunction(fn) {
return function(e) {
if (e.target.type !== "mouseenter") return;
fn.call(e.target)
};
}
.gnb {
float: left;
margin-left: 30px;
width: auto;
height: 100%;
}
.gnb>li {
float: left;
width: 150px;
height: 100%;
list-style: none;
}
.sub {
display: none;
}
.sub.show {
display: block;
}
<ul class="gnb">
<li class="gnbLi">
Why Mailchimp?
</li>
<li class="gnbLi" onmouseenter="myFunction()">
What You Can Do
<ol class="sub">
<li>Overview</li>
<li>Create</li>
</ol>
</li>
</ul>
Problem:
Basically what you have done is dealing with an array as a single element because of getElementsByTagName returns an array of ol in the whole page.
Solve:
1. you need to get the nested ol inside the li that's being hovered using
-event.target to get the clicked li.
- querySelector to get the ol under that li.
2. you need the ol to be displayed/removed depending on the event.
so only change the Javascript to be as the following and it will work
var ul = document.querySelector('.gnb');
var li = ul.children;
for (i = 0; i < li.length; i++) {
li[i].addEventListener('mouseenter', mouseenter);
li[i].addEventListener('mouseleave',mouseleave );
}
function mouseenter(event) {
var ol = event.target.querySelector('ol');
if(ol){
ol.style.display = 'block';
}
}
function mouseleave(event) {
var ol = event.target.querySelector('ol');
if(ol){
ol.style.display = 'none';
}
}
Your code is not correct and clean, I changed a little bit of your code:
(function () {
var ul = document.querySelector('.gnb');
var li = ul.children
var ol = document.getElementsByTagName('ol')[0];
var i;
for (i = 0; i < li.length; i++) {
li[i].addEventListener('mouseenter', myFunction(myshow));
li[i].addEventListener('mouseleave', myFunction(myhide));
}
function myshow() {
ol.style.display = 'block'
}
function myhide() {
ol.style.display = 'none'
}
function myFunction(fn) {
return fn;
}
})();
.gnb {
float: left;
margin-left: 30px;
width: auto;
height: 100%;
}
.gnb > li {
float: left;
width: 150px;
height: 100%;
list-style: none;
}
.sub {
display: none;
}
.sub.show {
display: block;
}
<ul class="gnb">
<li class="gnbLi">
Why Mailchimp?
</li>
<li class="gnbLi">
What You Can Do
<ol class="sub">
<li>Overview</li>
<li>Create</li>
</ol>
</li>
</ul>

How to add :hover and click event to element same time?

When I hover parent element his child is appear. When I click parent element his child also appear and when I click it again his child disappear. But then(after clicking parent element for disappearing child) when I hover parent element his child is not appearing. Why?
var parent = document.querySelector('nav > ul > li');
var children = document.querySelector('nav > ul > li > ul');
parent.addEventListener('click', function () {
if (children.style.display == 'block') {
children.style.display = 'none';
} else {
children.style.display = 'block';
}
});
nav > ul > li > ul {
display: none;
}
nav > ul > li:hover ul {
display: block;
}
li {
width: max-content;
}
ul {
padding: 0px;
}
<body>
<nav>
<ul>
<li>Parent
<ul>
<li>child</li>
<li>child</li>
</ul>
</li>
</ul>
</nav>
</body>
Thanks.
It is easier to toggle a class when the parent is clicked.
var parent = document.querySelector('nav > ul > li');
var children = document.querySelector('nav > ul > li > ul');
parent.addEventListener('click', function() {
children.classList.toggle("showIt");
});
nav>ul>li>ul {
display: none;
}
nav>ul>li:hover ul {
display: block;
}
li {
width: max-content;
}
ul {
padding: 0px;
}
.showIt {
display: block;
}
<body>
<nav>
<ul>
<li>Parent
<ul>
<li>child</li>
<li>child</li>
</ul>
</li>
</ul>
</nav>
</body>
You can easily avoid this by setting children.style.display to the empty string instead of assigning none to it when you want to hide the children.
EDIT:
Need a correction: Instead of undefined the empty string needs to be assigned to children.style.display to drop the override (see the text marked in italics - I had to correct that).
The code snippet should look like this:
var parent = document.querySelector('nav > ul > li');
var children = document.querySelector('nav > ul > li > ul');
parent.addEventListener('click', function () {
alert(children.style.display);
if (children.style.display == 'block') {
children.style.display = '';
} else {
children.style.display = 'block';
}
}, true);
Use basic programming composition
$('#target').on('click mouseover', function () {
// Do something for both
});

Javascript: Trying to make images draggable and compare objects

stacksocial newbie here.
I'm working on a web project that's basically a puzzle game that teaches people how to configure the parts for a computer. Think pcpartpicker meets a puzzle but without the purchasing.
I've created several javascript objects with different elements that I plan on comparing via elements. (e.g Motherboard object has socket element and CPU has a socket element and these elements must match to continue).
When you click on the object in the nav. menu, an click event occurs where you the corresponding picture appears. I want to make that picture draggable. The end goal is to drag all the pictures together and compare the elements to make sure everything works out and if objects don't match an alert will tell the user that its wrong.
Here's jsfiddle: http://jsfiddle.net/ciddo/sgf50j96/9/
HTML+Javascript
<title>Practice</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<!--[if lt IE 8]>
<script src ="http://ie7- js.googlecode.com/svn/version/2.1(beta2)/IE8.js"></script>
<![endif]-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<header>
<script>
var img1; //Motherboard
var img2; //CPU
var img3; //Memory
var img4; //Case
var img5; //Hard Drive
var img6; //Power Supply
</script>
<script>
function preloader() {
if (document.images) {
img1 = new Image();
img2 = new Image();
img3 = new Image();
img4 = new Image();
img5 = new Image();
img6 = new Image();
img1.src = "http://i.imgur.com/u4cQogt.jpg"; // Motherboard
img2.src = "http://i.imgur.com/snLSsMm.png"; // CPU
img3.src = "http://i.imgur.com/L8jc43K.png?1"; // Memory
img4.src = "http://i.imgur.com/oP6hsN0.jpg"; // Case
img5.src = "http://i.imgur.com/WrFaslA.jpg"; // Hard Drive
img6.src = "http://i.imgur.com/IMhS0uw.jpg";// Power Supply
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(preloader);
</script>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
<script>
//Need to call the folder containing images for all pc parts
//Variables that are used
var MoboSocket= ['LGA 1155','LGA 1150','LGA 1150','AM2','AM1','AM3'];
var MoboSize = ['ATX_Large','Micro-ATX_Medium','Mini-ITX_Small'];
var MoboMem = ['DDR','DDR2','DDR3','DDR4'];
var MoboPower = [25,50,75];
var intel = ['LGA 1155','LGA 1150','LGA 1150'];
var amd = ['AM2','AM1','AM3'];
var cpupower = [90,120,150,175,220];
var caseSize = ['Large','Medium','Small'];
var Memory = ['DDR','DDR2','DDR3','DDR4'];
var ram = [2,4,8,16];
var Power = [300,400,500,600,700];
var hddSize = [250,500,750,1000];
//Motherboards
var Motherboard = document.createElement("IMG");
var Motherboard1 = {
Socket:MoboSocket[Math.floor((Math.random()*MoboSocket.length))],
Size:MoboSize[Math.floor((Math.random()*MoboSize.length))],
RAM:MoboMem[Math.floor((Math.random()*MoboMem.length))],
Power:MoboPower[Math.floor((Math.random()*MoboPower.length))]
};
var Motherboard2 = {
Socket:MoboSocket[Math.floor((Math.random()*MoboSocket.length))],
Size:MoboSize[Math.floor((Math.random()*MoboSize.length))],
RAM:MoboMem[Math.floor((Math.random()*MoboMem.length))],
Power:MoboPower[Math.floor((Math.random()*MoboPower.length))]
};
var Motherboard3 = {
Socket:MoboSocket[Math.floor((Math.random()*MoboSocket.length))],
Size:MoboSize[Math.floor((Math.random()*MoboSize.length))],
RAM:MoboMem[Math.floor((Math.random()*MoboMem.length))],
Power:MoboPower[Math.floor((Math.random()*MoboPower.length))]
};
var Motherboard4 = {
Socket:MoboSocket[Math.floor((Math.random()*MoboSocket.length))],
Size:MoboSize[Math.floor((Math.random()*MoboSize.length))],
RAM:MoboMem[Math.floor((Math.random()*MoboMem.length))],
Power:MoboPower[Math.floor((Math.random()*MoboPower.length))]
};
//CPU Parts
var Intel_CPU = {
CPU:"Intel",
Socket:intel[Math.floor((Math.random()*intel.length))],
Power:cpupower[Math.floor(Math.random()*cpupower.length)]
};
var AMD_CPU = {
CPU:"AMD",
Socket:amd[Math.floor((Math.random()*amd.length))],
Power:cpupower[Math.floor(Math.random()*cpupower.length)]
};
//Cases
var Case1 = {
Size:caseSize[Math.floor((Math.random()*caseSize.length))]
};
var Case2 = {
Size:caseSize[Math.floor((Math.random()*caseSize.length))]
};
//Memory
var Memory1 = {
Type:Memory[Math.floor((Math.random()*Memory.length))],
Size:ram[Math.floor((Math.random()*ram.length))]
};
var Memory2 = {
Type:Memory[Math.floor((Math.random()*Memory.length))],
Size:ram[Math.floor((Math.random()*ram.length))]
};
var Memory3 = {
Type:Memory[Math.floor((Math.random()*Memory.length))],
Size:ram[Math.floor((Math.random()*ram.length))]
};
//Power Supply
var Power_Supply1 = {
Wattage:Power[Math.floor((Math.random()*Power.length))]
};
var Power_Supply2 = {
Wattage:Power[Math.floor((Math.random()*Power.length))]
};
//Hard Drives
var Hard_Drive1 = {
Size:hddSize[Math.floor(Math.random()*hddSize.length)]
};
var Hard_Drive2 = {
Size:hddSize[Math.floor(Math.random()*hddSize.length)]
};
//Generic Print Functions
function printPart(obj){
var str = "";
for (var x in obj){
str +="<br>"+obj[x];
}
return str;
};
function printMobo(obj){
var str1 = "<br> Socket: "+obj.Socket;
var str2 = "<br> Size: "+obj.Size;
var str3 = "<br> RAM Type: "+obj.RAM;
var str4 = "<br>"+obj.Power;
var str5 = str1+str2+str3+str4;
return str5;
};
function printCPU(obj){
var str1 = "<br> Type: "+obj.CPU;
var str2 = "<br> Socket: "+obj.Socket;
var str4 = "<br>"+obj.Power;
var str5 = str1+str2+str4;
return str5;
};
</script>
<script>
// Dragable moveable object code thingy
var ele = document.getElementsByClassName ("Motherboard")[0];
//ele.onmousedown = eleMouseDown;
ele.addEventListener ("mousedown" , eleMouseDown , false);
function eleMouseDown () {
stateMouseDown = true;
document.addEventListener ("mousemove" , eleMouseMove , false);
}
function eleMouseMove (ev) {
var pX = ev.pageX;
var pY = ev.pageY;
ele.style.left = pX + "px";
ele.style.top = pY + "px";
document.addEventListener ("mouseup" , eleMouseUp , false);
}
function eleMouseUp () {
document.removeEventListener ("mousemove" , eleMouseMove , false);
document.removeEventListener ("mouseup" , eleMouseUp , false);
}
</script>
<div id="jQuery">
<script>
$(function(){
});
</script>
</div>
</header>
<body>
<div class="">
<ul id="nav">
<li>Motherboards
<ul>
<li id="Mobo1"><a href="#">Motherboard 1:
<script type="text/javascript">
document.write(printMobo(Motherboard1));
</script>Watts
</a>
</li>
<li id="Motherboard2"><a href="#">Motherboard 2:
<script type="text/javascript">
document.write(printMobo(Motherboard2));
</script>Watts
</a>
</li>
<li id="Motherboard3"><a href="#">Motherboard 3:
<script type="text/javascript">
document.write(printMobo(Motherboard3));
</script>Watts
</a>
</li>
<li id="Motherboard4"><a href="#">Motherboard 4:
<script type="text/javascript">
document.write(printMobo(Motherboard4));
</script>Watts
</a>
</li>
</ul>
</li>
<li>CPUs
<ul>
<li id="CPU1"><a href="#">CPU 1: <script type="text/javascript">
document.write(printCPU(Intel_CPU));
</script>Watts
</a>
</li>
<li id="CPU2"><a href="#">CPU 2: <script type="text/javascript">
document.write(printCPU(AMD_CPU));
</script>Watts
</a>
</li>
</ul>
</li>
<li>Memory
<ul>
<li id="Memory1"><a href="#"><script type="text/javascript">
document.write(printPart(Memory1));
</script>GBs
</a>
</li>
<li id="Memory2"><a href="#"><script type="text/javascript">
document.write(printPart(Memory2));
</script>GBs
</a>
</li>
<li id="Memory3"><a href="#"><script type="text/javascript">
document.write(printPart(Memory3));
</script>GBs
</a>
</li>
</ul>
<li>Power Supplies
<ul>
<li id="PSU1"><a href="#"><script type="text/javascript">
document.write(printPart(Power_Supply1));
</script>Watts
</a>
</li>
<li id="PSU2"><a href="#"><script type="text/javascript">
document.write(printPart(Power_Supply2));
</script>Watts
</a>
</li>
</ul>
</li>
<li>Cases
<ul>
<li id="Case1"><a href="#"><script type="text/javascript">
document.write(printPart(Case1));
</script>
</a>
</li>
<li id="Case2"><a href="#"><script type="text/javascript">
document.write(printPart(Case2));
</script>
</a>
</li>
</ul>
</li>
<li>Hard Drives
<ul>
<li id="HDD1"><a href="#"><script type="text/javascript">
document.write(printPart(Hard_Drive1));
</script>GB
</a>
</li>
<li id="HDD2"><a href="#"><script type="text/javascript">
document.write(printPart(Hard_Drive2));
</script>GB
</a>
</li>
</ul>
</li>
</ul>
<div>
<script>
document.getElementById("Mobo1").addEventListener("click", function() {
document.body.appendChild(img1);
});
document.getElementById("CPU1").addEventListener("click", function() {
document.body.appendChild(img2);
});
document.getElementById("Memory1").addEventListener("click", function() {
document.body.appendChild(img3);
});
document.getElementById("PSU1").addEventListener("click", function() {
document.body.appendChild(img6);
});
document.getElementById("Case1").addEventListener("click", function() {
document.body.appendChild(img4);
});
document.getElementById("HDD1").addEventListener("click", function() {
document.body.appendChild(img5);
});
document.getElementsById(img1).addEventListener("click", function() {
alert("This Click worked");
});
</script>
</div>
</body>
</html>
CSS
body {
font-family: helvetica, arial, sans-serif;
background: #e3e3e3;
text-align: center;
}
/* MENU */
#nav {
background: #e5e5e5;
float: left;
margin: 0; padding: 0;
border: 1px solid white;
border-bottom: none;
}
#nav li a, #nav li {
float: left;
}
#nav li {
list-style: none;
position: relative;
}
#nav li a {
padding: 1em 2em;
text-decoration: none;
color: white;
background: #292929;
background: -moz-linear-gradient(top, black, #3c3c3c 1px, #292929 25px);
background: -webkit-gradient(linear, left top, left 25, from(black), color- stop(4%, #3c3c3c), to(#292929));
border-right: 1px solid #3c3c3c;
border-left: 1px solid #292929;
border-bottom: 1px solid #232323;
border-top: 1px solid #545454;
}
#nav li a:hover {
background: #2a0d65;
background: -moz-linear-gradient(top, #11032e, #2a0d65);
background: -webkit-gradient(linear, left top, left bottom, from(#11032e), to(#2a0d65));
}
/* Submenu */
.hasChildren {
position: absolute;
width: 5px; height: 5px;
background: black;
right : 0;
bottom: 0;
}
#nav li ul {
display: none;
position: absolute;
left: 0;
top: 100%;
padding: 0; margin: 0;
}
#nav li:hover > ul {
display: block;
}
#nav li ul li, #nav li ul li a {
float: none;
}
#nav li ul li {
_display: inline; /* for IE6 */
}
#nav li ul li a {
width: 150px;
display: block;
}
/* SUBSUB Menu */
#nav li ul li ul {
display: none;
}
#nav li ul li:hover ul {
left: 100%;
top: 0;
}
#nav li ul

How do I expand this CSS list?

I've gotten my menu to expand by one level, but cannot figure out how to get it to expand a second time. What am I doing wrong?
HTML:
<ul id="nav">
<li>Root
<ul>
<li>Option 1
<ul>
<li>Link3</li>
<li>Lin4</li>
<li>Link5</li>
<li>Link6</li>
</ul>
</li>
<li>Option2
<ul>
<li>Link3</li>
</ul>
</li>
</ul>
</li>
</ul>
CSS:
ul {
padding: 0px;
margin: 0px;
list-style: none;
background-color: #53BF58;
width: 10em;
}
li ul {
display: none;
background-color: #86EF8A;
}
li.active ul {
display: block;
}
li ul li ul {
display: none;
background-color: #86EF8A;
}
li ul li.active ul {
display:block;
}
Javascript:
function hideAll() {
var navList = document.getElementById("nav");
for (var i=0; i<navList.childNodes.length; i++) {
var node = navList.childNodes[i];
if (node.tagName == "LI") {
node.className = node.className.replace(new RegExp("\s?active", "i"), "");
}
}
}
window.onload = function () {
var navList = document.getElementById("nav");
for (var i=0; i<navList.childNodes.length; i++) {
var node = navList.childNodes[i];
if (node.tagName == "LI") {
node.onclick = function() {
hideAll();
this.className += " active";
}
}
}
}
childNodes only contains the direct children of the element--you need to recurse the childNodes of each node as well.
I highly recommend that you use a framework like jQuery (http://jquery.com) to make the code simpler:
http://jsfiddle.net/jDEhU/5/
$('#nav').delegate('li', 'click', function() {
var self = $(e.target), //get a reference to the clicked element
active = self.parents().andSelf() //select all li's that should be active
.addClass('active'); //and activate them
$('#nav .active').not(active).removeClass('active'); //deactivate others
});
I think the problem is that you're only looping through the first level of nodes in your list. You need to go through the child elements of each subsequent list and add an onClick function to keep it expanding.

Categories

Resources