I have a menu that contains 3 items. How can I change that the text to what it's selected from the menu?
HTML
<div id="dropdown-container">
<div id="index-tab" onclick="toggleMenu()">1</div>
<ul id="dropdown">
<li ><span class="current-browse">1</span>
<ul class="dropdown-items">
<li class="dropdown-item">2</li>
<li class="dropdown-item"">3</li>
</ul>
</li>
</ul>
</div>
JavaScript
function toggleMenu() {
var dropDown = document.getElementById('dropdown');
if(dropdown.style.display == "block") {
dropdown.style.display = "none";
} else {
dropdown.style.display = "block";
}
}
For example the menu currently showing:
1
1
2
3
If selected 2, it will show:
2
2
1
3
If selected 3 it will show :
3
3
1
2
Are you wanting to set the text of index-tab or the text of the current-browse span? Either way you need some click handlers on the li items that gets the element with the id or class of whichever one you want to set (Will need to get the anchor child of the index-tab div if it is used). Then replace the text element of the anchor or span. jQuery will make it a bit easier, but can be done either way. The jQuery example given will need to get the anchor child to then set text, and doing it when showing the menu is not what you want since no item is clicked yet.
Added toggleSelection() function:
event.preventDefault(); used to prevent links default action which is jumping to a location.
selectedItem references event.target (i.e. the element that was actually clicked), which is either the one of the .dropdown-items.
There's multiple exchanges between elements based on the .textContent of the selectedItem. At this point, #current-browse, and #index-tab a (the link in #index-tab) have a new .textContent and selectedItem has the previous item number.
All of that will not happen until #dropdown is clicked on and the event.target is determined. this is possible by the eventListener:
dropDown.addEventListener('click', toggleSelection, false);
SNIPPET
function toggleMenu() {
var dropDown = document.getElementById('dropdown');
if (dropDown.style.display == "block") {
dropDown.style.display = "none";
} else {
dropDown.style.display = "block";
}
}
function toggleSelection(event) {
event.preventDefault();
var selectedItem = event.target;
var targetItem = selectedItem.textContent;
var currentItem = document.getElementById('current-browse');
var prevItem = currentItem.textContent;
var extLink = document.querySelector('#index-tab a');
currentItem.textContent = targetItem;
extLink.textContent = targetItem;
selectedItem.textContent = prevItem;
}
var dropDown = document.getElementById('dropdown');
dropDown.addEventListener('click', toggleSelection, false);
<div id="dropdown-container">
<div id="index-tab" onclick="toggleMenu()">1
</div>
<ul id="dropdown">
<li><span id="current-browse">1</span>
<ul class="dropdown-items">
<li class="dropdown-item">2
</li>
<li class="dropdown-item">3
</li>
</ul>
</li>
</ul>
</div>
REFERENCE
addEventListener vs. onclick
'this' and EventHandlers
you need to write the toggleMenu() in a way that it changes the text of index-tab based on the value of dropdown:
$("#index-tab").text($(".dropdown-item option:selected").text())
Related
So I have a menu, I want it to display information accordingly, for example:
<ul id="menu-list">
<li id="about-me">About Me</li>
<li id="skills">Skills</li>
<li id="experience">Experience</li>
<li id="education">Education</li>
<li id="projects">Projects</l>
<li id="contacts">Contacts</li>
</ul>
and on my JS file I did this in order to access "li" elements:
let navMenu = document.getElementById("menu-list");
let menuList = navMenu.getElementsByTagName("li");
let skillsButton = document.getElementById("skills");
let skillsEvent = document.getElementById('main-section-skills').hidden = true;
(text that will display on click is pre-set to hidden = true)
The goal is to iterate through "li" items to find which one of those has ".hidden = false" value and change it to ".hidden = true" so that when you click on different menu buttons, each button will so only relevant info and others that are not relevant will bi hidden.
Thanks for your help.
You can get the array of children using element.children
https://developer.mozilla.org/en-US/docs/Web/API/Element/children
for (let child of navMenu.children) {
your logic here
}
For checking the class you can use element.hasClass or even:
element.style.display = 'none'
element.style.display = 'block'
Hi sorry in advance if this has already been asked but I can't find the answer.
I have a set of links that trigger certain ids to show onclick, it works but the one link is suppose to trigger 2 ids to show. My javascript knowledge is not great. Thanks for any help.
Here is my codepen https://codepen.io/louise-fourie/pen/abVdwyZ
<li>
Fitness & Wellness
</li>
<li>
Business
</li>
<li>
Arts & Entertainment
</li>
</ul>
<div class="articles">
<div id="el-57d5b6f71db32029">fitness</div>
<div id="el-e881a23a64890108">business</div>
<div id="el-65ebd7b2380005a1">art</div>
</div>
<script>
var divs = ["el-57d5b6f71db32029", "el-e881a23a64890108", "el-65ebd7b2380005a1"];
var visibleId = null;
function show(id) {
for(i = 0; i < divs.length; i++) {
if(visibleId !== id) {
visibleId = id;
}
}
hide();
}
function hide() {
var div, i, id;
for(i = 0; i < divs.length; i++) {
id = divs[i];
div = document.getElementById(id);
if(visibleId === id) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
</script>
There is something fishy with your show-hide logic.
Check out my suggestion below, where you can pass an array of IDs, which you want to show. All other elements will be hidden.
function onClick(elements) {
document.querySelectorAll('.articles div').forEach(articleDiv => articleDiv.style.display = 'none');
elements.forEach(element => {
const domEl = document.querySelector('#' + element)
domEl.style.display = 'block';
})
}
<ul>
<li>
Fitness & Wellness
</li>
<li>
Business
</li>
<li>
Arts & Entertainment
</li>
</ul>
<div class="articles">
<div id="fitness">fitness</div>
<div id="business">business</div>
<div id="art">art</div>
</div>
<script>
</script>
Your function seems to be running, but every time you receive an ID in your function, you hide everything else with the "hide" function, so in the end, the last ID sent, is the only one that will show, try this:
Call the function once, but pass the IDs as one string separated by commas
Business
Then change your "show" function like this:
function show(ids) {
let idArr = ids.split(",");
divs.forEach( x => {
div = document.getElementById(x);
div.style.display = (idArr.includes(x) ? "block" : "none");
});
}
What this does, is that it will create an array of IDs based on the parameter you send, and for each item it will check if the ID was sent and show/hide it.
Please let me know if this helps or if you need more details.
EDIT: Formatting in the JavaScript code and simplifying it. Please also note that here I am not validating if the an element with the ID exists, it is only to show you how it can work. It will need additional validations
You can try it
<ul>
<li>
Fitness & Wellness
</li>
<li>
Business
</li>
<li>
Arts & Entertainment
</li>
</ul>
<div class="articles">
<div id="el-57d5b6f71db32029" style="display:none;">fitness</div>
<div id="el-e881a23a64890108" style="display:none;">business</div>
<div id="el-65ebd7b2380005a1" style="display:none;">art</div>
</div>
<script>
document.querySelectorAll('.article-btn').forEach(item => {
item.addEventListener('click', event => {
show((item.getAttribute('data-id')).split(";"));
})
})
const show = (id) => {
document.querySelectorAll('.articles>div').forEach(item => {
if(id.includes(item.getAttribute('id'))){
item.style["display"] = "block";
}else{
item.style["display"] = "none";
}
});
}
</script>
Inline JavaScript is generally discouraged these days, so here's a solution that removes that dependency. It puts the ids of the list items into the dataset instead. You can then create an array from that dataset, iterate over the articles, and if the id is included in the array of ids either hide or show it.
// Cache the list and the articles
const ul = document.querySelector('ul');
const articles = document.querySelectorAll('.articles div');
// Add an event listener to the list
ul.addEventListener('click', handleClick, false);
function handleClick(e) {
// Get the node name and the dataset
// from the element that was clicked
const { nodeName, dataset } = e.target;
// Check that it was an anchor
if (nodeName === 'A') {
// Get an array of ids from the dataset
const ids = dataset
.ids.split(',')
.map(id => id.trim());
// Hide all the articles
articles.forEach(article => {
article.classList.add('hide');
});
// Show the articles where the id is in
// the list of ids
articles.forEach(div => {
if (ids.includes(div.id)) {
div.classList.remove('hide');
}
});
}
}
.hide { display: none; }
ul li:hover { cursor: pointer; color: red; }
<ul>
<li>
<a data-ids="el-57d5b6f71db32029">Fitness & Wellness</a>
</li>
<li>
<a data-ids="el-57d5b6f71db32029, el-e881a23a64890108">Business</a>
</li>
<li>
<a data-ids= "el-65ebd7b2380005a1">Arts & Entertainment</a>
</li>
</ul>
<div class="articles">
<div id="el-57d5b6f71db32029" class="hide">fitness</div>
<div id="el-e881a23a64890108" class="hide">business</div>
<div id="el-65ebd7b2380005a1" class="hide">art</div>
</div>
I have a piece of code that closes a drop down menu, if you click somehwere on the document other than the opened menu itself. I would like to get rid of jQuery, but I'm not sure how to translate this code to pure javascript.
$(document).ready(function() {
$(document).click(function(event) {
if (!$(event.target).closest('li.main').length) {
if ($('li.main').is(":visible")) {
$('#dropdown').hide();
}
}
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="main" onclick="ToggleMainMenu();"><span>All categories</span>
</li>
<li> Item 1
</li>
<li> Item 2
</li>
<li> Item 3
</li>
</ul>
Your click handler is doing the following:
if ( clicked object is a descendent of "li.main" AND "li.main" is visible)
hide "#dropdown"
If you add the onclick attribute to the node "li.main" or one of its descendents - as you added ToggleMainMenu in your comment - then you guarantee:
- The clicked item is "li.main" or is a descendent of "li.main"
- "li.main" is visible (since you cannot click an invisible item)
At this point you do not need comparisons any more and you only need to hide "#dropdown" in ToggleMainMenu function's body. Copying from javascript hide/show element :
document.getElementById("dropdown").style.display = "none";
p.s. I used jquery selector notation for brevity
Sometimes it's easier than you think. I found a solution:
document.addEventListener("DOMContentLoaded", function (event) {
document.addEventListener('click', function (e) {
var mainMenu = document.getElementById('main');
if (!mainMenu.contains(e.target)) {
document.getElementById('dropdown').style.display = 'none';
}
}, false);
});
I didn't know about contains.
function tab_menu(){
if (buttonObject.value == value){
document.getElementById("div1").style.display = "block";
}
}
i was trying when click to buttons check Button Value and show a div based on Button's Value and hide others divs it should show just one div at same time. I wonder there is a javascript Master who can solve this problem.
SCRIPT:
function tabmenu(buttonObject){
var value = buttonObject.value
var target = document.getElementById(value);
if(target) {
var siblings = target.parentNode.getElementsByTagName("DIV");
for(i=0;i<siblings.length;i++){
siblings[i].style.display = "none";
}
target.style.display = "block";
}
}
HTML:
<div>
<div id="tab1">Tab1</div>
<div id="tab2">Tab2</div>
<div id="tab3">Tab3</div>
</div>
<button onclick="tabmenu(this);" value="tab1">Tab1</button>
<button onclick="tabmenu(this);" value="tab2">Tab2</button>
find the tab to activate (assuming value = tab.id)
find the parent and hence it's siblings (assuming they are DIVs)
hide the siblings
show the target
You can see it working here: http://jsfiddle.net/4rWdQ/
I have little piece of javascript to show/hide divs based on which link is clicked in a list. Its not very eligant, but it works fine. What I'd like to do is to assign an active state the a list item depending on which div is showing. Here is my JS and HTML:
var ids=new Array('section1','section2','section3','section4');
function switchid(id){
hideallids();
showdiv(id);
}
function hideallids(){
//loop through the array and hide each element by id
for (var i=0;i<ids.length;i++){
hidediv(ids[i]);
}
}
function hidediv(id) {
//safe function to hide an element with a specified id
document.getElementById(id).style.display = 'none';
}
function showdiv(id) {
//safe function to show an element with a specified id
document.getElementById(id).style.display = 'block';
}
html:
<ul>
<li class="activeItem">One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
<div id="section1" style="display:block;">1111111</div>
<div id="section2" style="display:none;">2222222</div>
<div id="section3" style="display:none;">3333333</div>
<div id="section4" style="display:none;">4444444</div>
When section 2 (or whichever) is clicked, I'd like the class "activeItem" to be removed from the li it is currently on and applied to the current li. Is this possible with javascript? I think it is, but I can't figure out how to implement it client side.
Thanks!
If you're able to use jQuery (or something similar) as it has this ability built in: http://docs.jquery.com/Attributes - addClass/removeClass
Change your anchors to use the onclick event instead of the href javascript code.
<a onclick="switchid('section1');return false;">One</a>
Then pass the argument this into your switchid function. this is a javascript keyword which in this scenario refers to the element (a).
<a onclick="switchid('section1', this);return false;">One</a>
Now to make the switchid function modify the list.
function switchid(id, el){
hideallids();
showdiv(id);
// rejiggered for text nodes
var li = el.parentNode.parentNode.childNodes[0];
while (li) {
if (!li.tagName || li.tagName.toLowerCase() != "li")
li = li.nextSibling; // skip the text node
if (li) {
li.className = "";
li = li.nextSibling;
}
}
el.parentNode.className = "activeItem";
}
Try it out: http://jsbin.com/esazu3/edit