Basically I have an Id's Element in CSS that i'm trying to interact with via JavaScript. So I want to use:
document.getElementById('dropMenu').style.opacity = '0';
on
#dropMenu li {
opacity: 1;
}
but I cant work out how to interact with the li part specifically, is it even possible?
Thanks,
James
HTML
<html>
<head>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<link href="./stylesheet.css" type="text/css" rel="stylesheet">
<title>Index</title>
<script>
function dropMenu(){
if (document.getElementById('dropMenu').style.height != '151px')
{
document.getElementById('dropMenu').style.height = '151px';
document.querySelectorAll('dropMenu li').style.opacity = '1';
console.log("showingObj");
}
else
{
document.getElementById('dropMenu').style.height = '0px';
document.querySelectorAll('dropMenu li').style.opacity = '0';
console.log("hideObj:");
}
}
</script>
</head>
<body>
<nav>
<div id="mainMenu">
<i class="fa fa-bars" onclick="dropMenu()"></i><p>Page Title</p>
</div>
<div id="dropMenu">
<ul>
<li>
<i class="fa fa-pencil fa-5x" id="dm1" style="background: #00bcd4;"></i>
<p style="background: #00acc1;">Projects</p>
</li>
<li>
<i class="fa fa-film fa-5x" id="dm1" style="background: #8bc34a;"></i>
<p style="background: #7cb342;">Media</p>
</li>
<li>
<i class="fa fa-camera-retro fa-5x" id="dm1" style="background: #ffc107;"></i>
<p style="background: #ffb300;">Photography</p>
</li>
<li>
<i class="fa fa-info-circle fa-5x" id="dm1" style="background: #e51c23;"></i>
<p style="background: #dd191d;">About Me</p>
</li>
</ul>
</div>
</nav>
</body>
As an alternative to having to grab the li list, looping over it and programmatically setting the styles you could just add/remove a class on the dropMenu element by using the classList add/remove methods, or if supporting older browsers manipulate the className property
CSS
#dropMenu li {
opacity: 1;
}
#dropMenu.hideli li {
opacity: 0;
}
JS
//to add
document.getElementById("dropMenu").classList.add("hideli");
//to remove
document.getElementById("dropMenu").classList.remove("hideli");
//Quick and dirty could be improved
var ele = document.getElementById("dropMenu");
//to add
ele.className += " hideli";
//to remove
ele.className = ele.className.replace("hideli","");
Demo
setTimeout(function(){
document.getElementById("dropMenu").classList.add("hideli");
},1000);
setTimeout(function(){
document.getElementById("dropMenu").classList.remove("hideli");
},3000);
#dropMenu li {
opacity:1;
}
#dropMenu.hideli li {
opacity:0;
}
<div id="dropMenu">
<ul>
<li>Li 1</li>
<li>Li 2</li>
<li>Li 3</li>
<li>Li 4</li>
</ul>
</div>
Yes, this is possible, but requires some extra JavaScript
1) Using getElementById with getElementsByTagName
var parent = document.getElementById('dropMenu');
var children = parent.getElementsByTagName('li');
// Loop child elements here, using forEach...
Array.prototype.forEach.call(children, ...);
2) Using querySelectorAll
var children = document.querySelectorAll('#dropMenu li');
// Loop child elements here...
Array.prototype.forEach.call(children, ...);
3) If you're open to using jQuery, it's easily done (similar to querySelector)
$('#dropMenu li').each(...);
Within the forEach (or a standard forloop), you'll interact directly with the element.
For example. using a standard for loop:
for (var i = 0, len = children.length; i < len; i++) {
children[i].style.opacity = 0;
}
Using forEach (if you don't mind compatibility issues) might look like this:
Array.prototype.forEach.call(children, function(el){
el.style.opacity = 0;
})
Use querySelectorAll and loop through the items changing their style
var items = document.querySelectorAll('#dropMenu li');
for(var i=0;i<items.length;i++){
items[i].style.opacity="1"
}
in js you can write it as
var elems = document.querySelectorAll('#dropMenu li');
for(var index = 0; index < elems.length; index++) {
elems[index].style.opacity = 0;
}
Your getElementById('dropMenu') is ok, then you can add "sub-query" for all li elements, and scan it:
var dropmenu = document.getElementById('dropMenu');
var lis = dropmenu.getElementsByTagName('li');
for(var i = 0; i < lis.length; i++) {
lis[i].style.opacity = 0;
}
Related
I am trying to achieve multiple accordion lists with dynamic height concepts, I am debugging for hours and not able to understand where I went wrong. The code I have tried so far.
The scenario I was trying on is when the main categories are clicked with the dynamic height it will show off and that same scenario will happen for its sub-categories also. I am stuck on how to take the inner sibling method.
Note: I am trying to achieve this in vanilla javascript.
Any help will be appreciated !!
var headers = document.querySelectorAll('.first-ul-1 .ul, .sub-ul-1-a ul');
window.addEventListener("DOMContentLoaded", () => {
for (var i = 0; i < headers.length; i++) {
headers[i].addEventListener('click', openAccordion);
}
function openAccordion(e) {
var parent = this.parentElement;
var article = this.nextElementSibling;
if (!parent.classList.contains('open')) {
parent.classList.add('open');
article.style.maxHeight = article.scrollHeight + 'px';
} else {
parent.classList.remove('open');
article.style.maxHeight = '0px';
}
}
.drop-down-menu,
.sub-ul-2-a{
max-height: 0px;
overflow: hidden;
transition: max-height 350ms ease-in-out;
}
<nav id="navigation" class="main-nav">
<ul class="main-nav-list first-ul-1">
<li>
<p href="#">Types</p>
<div class="drop-down-menu">
<div class="menu-container">
<ul class="main-nav-list sub-ul-1-a">
<li>
<a href="#">Type
of season</a>
<ul class="main-nav-list sub-ul-2-a">
<li>
<a href="#">Summer
</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</li>
</ul>
</nav>
I'm using vanilla JS for some reasons and trying to replace div content while click on li.
I'm tried to replace by function(target, source) but target is always = id.
So I'm clone my function and onclick li insert 2 functions + params.
<body>
<li onClick="replaceContentInContainer('target', 'replace_target_div2'); replaceContentInContainerTwo('targetTwo', 'replace_target_div2_02')">View Div 2</li>
<li onClick="replaceContentInContainer('target', 'replace_target_div3'); replaceContentInContainerTwo('targetTwo', 'replace_target_div3_02')">View Div 3</li>
<div>
<span id="target">div1</span>
</div>
<div style="display:none">
<span id="replace_target_div2">div2</span>
</div>
<div style="display:none">
<span id="replace_target_div3">div3</span>
</div>
<div>
<span id="targetTwo">div1</span>
</div>
<div style="display:none">
<span id="replace_target_div2_02">div2 02</span>
</div>
<div style="display:none">
<span id="replace_target_div3_02">div3 03</span>
</div>
</body>
<script>
function replaceContentInContainer(target, source) {
document.getElementById(target).innerHTML = document.getElementById(source).innerHTML;
}
function replaceContentInContainerTwo(targetTwo, sourceTwo) {
document.getElementById(targetTwo).innerHTML = document.getElementById(sourceTwo).innerHTML;
}
</script>
I would like to have elegant way to do so.
I think what you mean is that you want to keep your HTML clean.
You could use a click eventhandler on all li within a certain ul.
HTML
<ul id="theList">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
JS add Click event handler
// Get all list items in ul with id 'theList'
var listItems = document.querySelectorAll('#theList li');
// Add a click event handler on each list item
for (i = 0; i < listItems.length; i++) {
listItems[i].addEventListener("click", function(){
console.log(this) // This is your target html
});
}
For the last step I'm not sure what you want. I don't know how your source is chosen. I will edit if you explain it more.
You can user this code:
<body>
<li onClick="replaceContentInContainer('target', 'div2');">View Div 2</li>
<li onClick="replaceContentInContainer('target', 'div3')">View Div 3</li>
<div>
<span class="target">div1</span>
</div>
<div>
<span class="target">div1</span>
</div>
</body>
<script>
function replaceContentInContainer(div, text) {
var ids = document.getElementsByClassName(div);
for (var i = 0; i < ids.length; i++) {
ids[i].innerText = text;
}
}
</script>
I need to hide li has a span child without jquery, how can i do it?
<ul class="select2-results__options" role="tree" id="select2-upsell_ids-results">
<li class="select2-results__option">first (#404)</li>
<li class="select2-results__option" >second (#496)</li>
<li class="select2-results__option">abc (#2482)</li>
<li class="select2-results__option">defg (#2484)<span class="description">Size: 47</span></li>
<li class="select2-results__option">hil (#2485)<span class="description">Size: 46,5</span></li>
</ul>
To be fair, #j08691's answer is perfectly valid and neat, and is absolutely not jQuery.
However, if #Geme doesn't like it, take a look at the code below. Trust me none of the code below contains any jQuery.
You can check if there is a span element inside each li by looping through the childNodes of each li.
If the childNode has a constructor of HTMLSpanElement, it is a span element.
var lists = document.getElementsByClassName('select2-results__option'); // NOT JQUERY
var i = 0;
var x = 0;
// NOT JQUERY AT ALL
for (; i < lists.length; i++)
for (; x < lists[i].childNodes.length; x++)
if (lists[i].childNodes[x].constructor === HTMLSpanElement){
lists[i].style.display = 'none';
break;
}
/* ALTERNATIVE */
// NOT JQUERY TOO
Array.prototype.forEach.call(lists, function(li){
var child = li.childNodes,
i = 0,
len = child.length;
for (; i < len; i++)
if (child[i].constructor === HTMLSpanElement)
li.style.display = 'none';
});
<ul class="select2-results__options" role="tree" id="select2-upsell_ids-results">
<li class="select2-results__option">first (#404)</li>
<li class="select2-results__option" >second (#496)</li>
<li class="select2-results__option">abc (#2482)</li>
<li class="select2-results__option">defg (#2484)<span class="description">Size: 47</span></li>
<li class="select2-results__option">hil (#2485)<span class="description">Size: 46,5</span></li>
</ul>
You can use document.querySelectorAll('li > span') to select the elements and then loop to hide them.
var items = document.querySelectorAll('li > span')
for (var item of items) {
item.parentNode.style.display = 'none';
}
<ul class="select2-results__options" role="tree" id="select2-upsell_ids-results">
<li class="select2-results__option">first (#404)</li>
<li class="select2-results__option">second (#496)</li>
<li class="select2-results__option">abc (#2482)</li>
<li class="select2-results__option">defg (#2484)<span class="description">Size: 47</span></li>
<li class="select2-results__option">hil (#2485)<span class="description">Size: 46,5</span></li>
</ul>
I want to know how to change the style of an particular <li> in a particular <ul> by JavaScript
My code goes something like this
<ul id="menu">
<li id="number1">1</li>
<li id="number2">2</li>
</ul>
Now let's say I want to change the background color of the li#number1 of the ul#menu using JavaScript.
This is your solution in plain JavaScript:
var el = document.querySelector('#number1');
el.addEventListener('click', function(e) {
el.style.backgroundColor = 'blue';
});
Here is a solution using javascript and button.
<script>
function doSth(){
var nodes = document.getElementById("menu").getElementsByTagName("li");
for(var i=0; i<nodes.length; i++) {
if (nodes[i].id == 'number2') {
nodes[i].style.background = "blue";
}
}
}
</script>
<ul id="menu">
<li id="number1">1</li>
<li id="number2">2</li></ul>
<input type="button" onClick="doSth();" value="Click here"/>
i have this assignment running good but stuck on where i have to reset values. i have tried .removeEventListener which doesn't work the way i want it and also i don't wanna reload the page. Below are my codes...
Html
<!DOCTYPE html>
<html>
<head>
<title>Table Soccer Teams</title>
<link rel="stylesheet" type="text/css" href="soccer.css" />
<script type="text/javascript" src="table_soccer.js" ></script>
</head>
<body>
<a id="reset" href ="#" class="btn" >Reset</a>
<div id="soccer_field">
<div class="players" onsubmit="return(validateForm ());">
<h2>Possible Players</h2>
<ul id="first">
<li class="list-item">Player 1</li>
<li class="list-item">Player 2</li>
<li class="list-item">Player 3</li>
<li class="list-item">Player 4</li>
<li class="list-item">Player 5</li>
<li class="list-item">Player 6</li>
<li class="list-item">Player 7</li>
<li class="list-item">Player 8</li>
</ul>
<p class="three">Click on names above to select player </p>
</div>
<div class="actual_players">
<h3>Actual Players</h3>
<ul id="actual-players" ></ul>
<p class="two">Click button below to generate Teams</p>
<a id="generate" href ="#" class="btn">Click here</a>
</div>
<div class="teams">
<h1>Teams</h1>
<h4>Team 1</h4>
<p id="forward-one"><span>Forward:</span></p>
<p id="defender-one"><span>Defender:</span></p>
<h5>Team 2 </h5>
<p id="forward-two"><span>Forward:</span></p>
<p id="defender-two"><span>Defender:</span></p>
</div>
</div>
</body>
</html>
Javascript
function init(){
var listItems = document.getElementsByClassName("list-item");
for(var i=0; i<listItems.length; i++){
listItems[i].addEventListener("click", function(){
var text = this.innerHTML;
var liElement = document.createElement("LI");
liElement.ClassName = "test";
var text = document.createTextNode(text);
liElement.appendChild(text);
var lis = document.getElementById("actual-
players").getElementsByTagName("li");
if (lis.length == 4){
alert("Don't let more than four players");
} else {
document.getElementById("actual-
players").appendChild(liElement);
this.remove();
}
});
}
document.getElementById("generate").addEventListener("click",
function(){
var temp = [];
var t = document.getElementById("actual-
players").getElementsByTagName("li");
for(var i=0; i<t.length; i++){
temp.push(t[i]);
}
var x = temp.length;
if (x < 4 || x == null) {
alert("Actual players field must not be empty or have less
than 4 players");
return false;
}
var positions = ["forward-one", "defender-one", "forward-two",
"defender-two"];
for (var i = 0; i < 4; i++){
var index = Math.floor(Math.random()*temp.length);
var player = temp[index];
document.getElementById(positions[i]).appendChild(player);
temp.splice(index, 1);
}
});
Below is where i wanna write my reset codes... i want the distributed players to be removed when reset is clicked...
document.getElementById("reset").addEventListener("click", function()
{
});
Here is the doc of element.removeEventListener
Try to pass a named function (not an anonymous one) to addEventListener and removeEventListener.
var generate_element = document.getElementById("generate");
var generate_func = function(){...};
generate_element.addEventListener("click",generate_func);
// and later in your code
generate_element.removeEventListener("click",generate_func);
Removing the event listener will not change the DOM tree itself.
You can either populate it using an id and use
document.removeChild(document.getElementById("yourId"))
but then you need to keep track of "yourId" when creating it. -In case you will need this value later it could make sense.
OR
you can simply clear the content:
document.getElementById("forward-one").innerHTML = "<p id='forward-one'><span>Forward:</span></p>";
but in that case make it nicer and move the id to a div in html:
<p><span>Forward:</span><div id="forward-one">Apa, www</div></p>
and then use:
document.getElementById("forward-one").innerHTML = "";