How to hide a menu when clicked on any menu-item? - javascript

I can not find where is the problem. Any idea about hiding on clicking any menu-item?
var button = document.getElementById("#1");
var menu = document.getElementById("#menu");
button.addEventListener('click', function(event) {
if (menu.style.display == "block") {
menu.style.display = "none";
} else {
menu.style.display == "block";
}
});
<ul id="menu">
<li>Home</li>
<li>Model S</li>
<li>Model 3</li>
<li>Model X</li>
<li>Model Y</li>
</ul>

You cannot get document.getElementById("#1") with #. getElementById is already an id selector, so you don't need to have #.
menu.style.display, you don't have inline styles for menu, your condition won't pass for the first time.
You also cannot have multiple id in your elements because id should be unique. In that case, you should use class instead (I added menu-item classes for element selectors)
I've tried to change your code with some comments
//get all menu items
var menuItems = document.querySelectorAll(".menu-item");
var menu = document.getElementById("menu");
for (const menuItem of menuItems) {
//add click events to menu items
menuItem.addEventListener('click', function(event) {
//hide menu if click on menu item
menu.style.display = "none";
});
}
<ul id="menu">
<li>Home</li>
<li>Model S</li>
<li>Model 3</li>
<li>Model X</li>
<li>Model Y</li>
</ul>

Related

HTML Drag and Drop, dragover event returns the child element and not the parent

In the provided example, when I drag any element over the "Category1" the console.log outputs the child element "DIV" instead of the parent element "LI".
Any solutions would be appreciated.
document.addEventListener('dragover', function (event) {
event.stopPropagation();
event.preventDefault();
console.log(event.target.tagName);
}, true);
<ul>
<li draggable='true'><div draggable="false">Category 1</div>
<ul>
<li draggable='true'> * Item 1 </li>
<li draggable='true'> * Item 2 </li>
<li draggable='true'> * item 3 </li>
</ul>
<li draggable='true'><div draggable="false">Category 2</div>
<ul>
<li draggable='true'> * Item 1 </li>
<li draggable='true'> * Item 2</li>
</ul>
</li>
</li>
</ul>
use "drag" instead of "dragover" in EventListener.
document.addEventListener('drag', function (event) {
event.stopPropagation();
event.preventDefault();
console.log(event.target.tagName);
},true);
Was thinking of using a FOR loop to get through the DOM until I find the LI.
function getfirstLI(el)
{
for (i = 0; i < 10; i++) {
if (el.tagName == "LI") return el;
if (el.tagName == "UL") return null;
if (el.tagName == "body") return null;
el = el.parentNode;
}

JQuery on click <li> interference

Ok, the problem is a little hard to explain but I'll do my best.
when I click on one <li> element everyone else inside him is clicked.
I try to create categories and subcategories.but whenever I click on a category a subcategory is also called!
<li class="has-sub product_type" id="category1"> <a>Lorem1</a>
<ul>
<li class="product_sub_type" id="subcategory1"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory2"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory3"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory4"><a>Lorem2</a></li>
</ul>
</li>
$(document).ready(function(){
var type_id = '';
$(".all_products").fadeOut("fast");
$(".product_type").on("click", function(event) {
alert("Dbg");
type_id = event.currentTarget.id;
$(".big_categoryes").fadeOut("fast");
$(".all_products").fadeIn("smooth");
sortProducts(type_id);
});
var type_sub_id = '';
$(".product_sub_type").on("click", function(event) {
type_sub_id = event.currentTarget.id;
sortSubProducts(type_sub_id);
});
});

Javascript: Selecting List from UL

var ul = document.getElementById("parent-list");
document.querySelectorAll("#parent-list li").onclick = function() {
alert('click!');
}
<ul id="parent-list">
<li id="item-1">Item 1</li>
<li id="item-2">Item 2</li>
<li id="item-3">Item 3</li>
<li id="item-4">Item 4</li>
<li id="item-5">Item 5</li>
<li id="item-6">Item 6</li>
<li id="item-7">Item 7</li>
<li id="item-8">Item 8</li>
<li id="item-9">Item 9</li>
</ul>
I'm trying to have an alert popup of the item clicked when I click on a "li" element with javascript only. I know how to do in jquery but I can't figure out how to do it with javascript.
fiddle: https://jsfiddle.net/7jcksznz/1/
querySelectorAll returns an HTML collection. You would need to attach the event to each one. You would need to loop over the collection.
var lis = document.querySelectorAll("#test li");
for (var i = 0; i < lis.length; i++) {
lis[i].addEventListener("click", function() {
console.log(this.innerHTML);
});
}
<ul id="test">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
A better option is to add one click on the UL and use the event to determine which li was clicked.
document.getElementById("test").addEventListener("click", function(event) {
var li = event.target;
console.log(li.innerHTML);
});
<ul id="test">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
document.querySelectorAll("#parent-list li") get a collection of HTMLElement,so,you can do like this:
window.onload = function()
{
var ul = document.getElementById("parent-list");
ul.onclick = function(e)
{
if(e.target.tagName = "LI")
{
alert(1);
}
}
}
querySelectAll returns array of nodes.
you have to iterate over the nodes to add the event listner.
var ul = document.getElementById("parent-list");
var li_items = document.querySelectorAll("#parent-list li");
for (var i = 0 ; i < li_items.length ; i++)
li_items[i].onclick = function (){alert(this.id);}
Use an event-listener targeted on each element rather than directly assigning an onclick function to a NamedNodeMap.
/* get an array of list items */
var items = Array.prototype.slice.call(
document.querySelectorAll('li[id|="item"]')
);
/* add event-listener to each item */
items.forEach(function(item) {
item.addEventListener('click', clickAlert, false);
});
/* click function */
function clickAlert(evt) {
alert(evt.target.id +' clicked!');
}
See:
Array.prototype.slice
Array.prototype.forEach
eventTarget.addEventListener
NamedNodeMap

Javascript/jQuery - On hover over a li element, change class of another li element

i am having some trouble with the menu bar on this website: http://www.re-generation.ro/ro/campanii/minerit-aurifer .
Now, the second li element is active. What i want to do, is that on hover over any other li element in the menu, the class of the current active li element becomes blank and on on hover out, it becomes active again. If you visit the link you can easily understand what i what.
If you need any information pls ask.
thank you in advance!
My code:
var lis = document.getElementsByTagName('ul');
for (var i=0, len=lis.length; i<len; i++){
lis[i].onmouseover = function(){
var firstDiv = this.getElementsByTagName('li')[1];
firstDiv.className = '';
var ul = $(this).parent(document.this.getElementsByTagName('ul')[1]);
ul.className = '';
};
lis[i].onmouseout = function(){
var firstDiv = this.getElementsByTagName('li')[1];
firstDiv.className = 'active';
};
};
EDIT: Thank you all for your answers! That really helped!
The first thing you probably want to do is assign two different states/classes: active and current. One tells you which one should be shown, and the other actually toggles the visibility.
$('#menu').on('mouseover', '> li', function(e) {
# attach hover event to the menu, and check which LI you are hovering
if (!$(this).hasClass('.current)')) {
$('.current', '#menu').removeClass('active');
}
}).on('mouseout', '> li', function (e) {
if (!$(this).hasClass('.current)')) {
$('.current', '#menu').addClass('active');
}
});
Here you are selecting just the direct descendants and updating the class, provided it's not the currently active list item.
HTML:
<ul id="menu">
<li>Item 1</li>
<li class="current active">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>​
JavaScript:
$('#menu li').on('mouseover', function() {
var li$ = $(this);
li$.parent('ul').find('li').removeClass('active');
li$.addClass('active');
})
.on('mouseout', function() {
var li$ = $(this);
li$.removeClass('active');
li$.parent('ul').find('li.current').addClass('active');
});​
DEMO
I would use JQuery for this. Something like this:
$('li').hover(function(){
$('li.active').removeClass('active').addClass('normal');
});
$('li').mouseleave(function(){
$('li.normal').removeClass('normal').addClass('active');
});
What you're missing is a way to remember what the default state is. Here is my answer, and a Fiddle
HTML:
<ul class="menuWithDefault">
<li>Link One</li>
<li class="active">Link One</li>
<li>Link One</li>
<li>Link One</li>
</ul>
Javascript:
$(".menuWithDefault").each(function() {
var defaultItem = $(this).find(".active").first();
$(this).find("li").hover(function() {
defaultItem.toggleClass('active', false);
$(this).toggleClass('active', true);
}, function() {
$(this).toggleClass('active', false);
defaultItem.toggleClass('active', true);
});
});​
​
$(document).ready(function(){
$('li').hover(function(){
$(this).addClass('active').siblings().removeClass('active')
});
});
li.active{
color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
</ul>

JavaScript expandable treeview lightweight

I wanted a lightweight solution so i found this one, however it only expands on clicking plus sign "+" next to the name of expandable category. I replaced + for red square and - for blue square for this demonstration to work.
Live code at: http://jsfiddle.net/2VXuk/2/
I need help modifying it to make any sub level that is expandable to be category that's not a link and upon clicking on its name expand its content.
Would be great to have option to make it a category - expand on click or link expand on + click and redirect on name click.
e.g.
<ul id="sitemap">
<li><a class="category" href="#">expands only</a>
<ul>
<li>Sample</li>
<li>Sample</li>
<li><a class="category_and_link" href="psy.html">Link to page or expand on + button</a>
<ul>
<li>Sample</li>
<li>Sample</li>
<li>Sample</li>
<li>Sample</li>
<li>Sample</li>
</ul>
</li>
<li>Fourth link</li>
<li>Fifth link</li>
</ul>
</li>
</ul>
<script type="text/javascript">
this.sitemapstyler = function(){
var sitemap = document.getElementById("sitemap")
if(sitemap){
this.listItem = function(li){
if(li.getElementsByTagName("ul").length > 0){
var ul = li.getElementsByTagName("ul")[0];
ul.style.display = "none";
var span = document.createElement("span");
span.className = "collapsed";
span.onclick = function(){
ul.style.display = (ul.style.display == "none") ? "block" : "none";
this.className = (ul.style.display == "none") ? "collapsed" : "expanded";
};
li.appendChild(span);
};
};
var items = sitemap.getElementsByTagName("li");
for(var i=0;i<items.length;i++){
listItem(items[i]);
};
};
};
window.onload = sitemapstyler;
</script>
See my fork of your jsFiddle. The basic idea is to grab the a element...
var a = li.getElementsByTagName("a")[0];
and add an event handler to it as well.
if (!a.hasAttribute("href"))
a.onclick = showHide;
For non-links, just leave out the href attribute.

Categories