How to change attributes of only first child divs within a div - javascript

I have this function that that will reset the display attributes of all divs within a div to none then sets the selected one to block.
function Test(id)
{
var allFiles = document.getElementById("FileContainer").getElementsByTagName("div");
for(i=0; i< allFiles.length; i++)
allFiles[i].style.display="none";
var selected = document.getElementById(id);
selected.style.display="block";
}
Problem is though that this also sets the display to none for the child divs of the child div as well. How can I make it only apply to the first child level?
<div id="FileContainer">
<div id="test-1"> //Set display to none
<div id="test1.1"> //Do not set display to none
</div>
<div id="test-2"> //Set display to none
<div id="test1.1"> //Do not set display to none
</div>
</div>

Expanding the solution given here, you can either assign the variable allFiles to all direct child divs using the CSS Child Combinator selector ">" like this:
/* JavaScript */
var allFiles = document.querySelectorAll("#FileContainer > div");
var btn = document.querySelector("button");
var val = document.getElementById("val");
function func() {
allFiles.forEach(div => {
if (div.id == val.value) {
div.style.display = "none";
}
});
}
btn.addEventListener("click", func);
/* CSS */
#FileContainer {color: white;}
#test-1 {background-color: green;}
#test-2 {background-color: green;}
#test3 {background-color: red;}
#test4 {background-color: red;}
<!--HTML-->
<div id="FileContainer">
<div id="test-1">Direct Child 1<div id="test3">Not Direct Child 1</div></div>
<div id="test-2">Direct Child 2<div id="test4">Not Direct Child 2</div></div>
</div>
<hr>
<input type="text" id="val" />
<button>Check ID</button>
<hr>
jsFiddle using the CSS Child Combinator selector ">": http://jsfiddle.net/AndrewL64/5nuedztx/20/
Or if you are sure there are no other elements directly under your #FileContainer div that you want to target, you can use the .children property like this:
/* JavaScript */
var allFiles = document.querySelector("#FileContainer").children;
var btn = document.querySelector("button");
var val = document.getElementById("val");
function func(){
[].forEach.call(allFiles, (div => {
if (div.id == val.value) {
div.style.display = "none";
}
}))
}
btn.addEventListener("click", func);
/* CSS */
#FileContainer {color: white;}
#test-1 {background-color: green;}
#test-2 {background-color: green;}
#test3 {background-color: red;}
#test4 {background-color: red;}
<!-- HTML -->
<div id="FileContainer">
<div id="test-1">Direct Child 1<div id="test3">Not Direct Child 1</div></div>
<div id="test-2">Direct Child 2<div id="test4">Not Direct Child 2</div></div>
</div>
<hr>
<input type="text" id="val" />
<button>Check ID</button>
<hr>
jsFiddle using .children : http://jsfiddle.net/AndrewL64/zkgjxhfc/30/

Check this
<div id="FileContainer">
<div id="test-1"> //Set display to none
<div id="test1-1">
</div> //Do not set display to none
</div>
<div id="test-2"> //Set display to none
<div id="test1-1"> //Do not set display to none
</div>
</div>
</div>
<button onclick="Test('test-2')">Click</button>
<script>
function Test(id){
var el = document.querySelectorAll("div#FileContainer > div");
for (var i = 0; i < el.length; i++){
//if id != requested id then hide it
if(el[i].id != id){
el[i].style.display = "none";
}
}
}
</script>

Related

change properties of two divs with one onclick and querySelectorAll()

I have multiple elements that are seperatet in two divs. The first div contains a Text and the second div a color.
When I click on one element the text and color should change and if I click it again it should change back.
The problem is that no matter which one I click, its always the last one which changes.
The HTML part:
<style>
.colorGreen {
background-color: green;
}
.colorRed {
background-color: red;
}
</style>
<div class="box2">Text1</div>
<div class="box1 colorGreen">O</div>
<div class="box2">Text1</div>
<div class="box1 colorGreen">O</div>
<div class="box2">Text1</div>
<div class="box1 colorGreen">O</div>
The JavaScript part:
<script type='text/javascript'>
var box1Temp = document.querySelectorAll(".box1");
var box2Temp = document.querySelectorAll(".box2");
for (var i = 0; i < box1Temp.length; i++) {
var box1 = box1Temp[i];
var box2 = box2Temp[i];
box2.onclick = box1.onclick = function() {
if (box1.classList.contains("colorGreen")) {
box1.classList.add("colorRed");
box1.classList.remove("colorGreen");
box2.innerHTML = "Text2";
} else {
box1.classList.add("colorGreen");
box1.classList.remove("colorRed");
box2.innerHTML = "Text1";
}
}
}
</script>
It works, when I use only one div.
Then I can use 'this', instead of the 'box1' variable, to addres the right element.
But if I replace 'box1' with 'this' its still the text div that changes.
(I know it's obvious that this is happening, but I'm lost)
With a few small tweaks, this can be written a lot more cleanly:
// Capture click event for parent container, .toggle-set
for (const ele of document.querySelectorAll(".toggle-set")) {
ele.addEventListener("click", function() {
// Grab text and color elements
const textToggle = ele.querySelector(".toggle-text");
const colorToggle = ele.querySelector(".toggle-color");
// Toggle text
// NOTE: This could use further refinement with regex or something similar to strip whitespace before comparison
textToggle.textContent = textToggle.textContent == "Text1" ? "Text2" : "Text1";
// Toggle css classes
colorToggle.classList.toggle("colorGreen");
colorToggle.classList.toggle("colorRed");
});
}
.colorGreen { background-color: green; }
.colorRed { background-color: red; }
<div class="toggle-set">
<div class="toggle-text">Text1</div>
<div class="toggle-color colorGreen">
O
</div>
</div>
<div class="toggle-set">
<div class="toggle-text">Text1</div>
<div class="toggle-color colorGreen">
O
</div>
</div>
Your code is so confused
You were right for the this option.
you can do with simple onclick function :
function change(el){
box1 = el.querySelector('.box1');
box2 = el.querySelector('.box2');
if (box1.classList.contains("colorGreen")) {
box1.classList.add("colorRed");
box1.classList.remove("colorGreen");
box2.innerHTML = "Text2";
} else {
box1.classList.add("colorGreen");
box1.classList.remove("colorRed");
box2.innerHTML = "Text1";
}
}
<style>
.colorGreen {
background-color: green;
}
.colorRed {
background-color: red;
}
</style>
<div onclick="change(this)">
<div class="box2">Text1</div>
<div class="box1 colorGreen">O</div>
</div>
<div onclick="change(this)">
<div class="box2">Text1</div>
<div class="box1 colorGreen">O</div>
</div>
<div onclick="change(this)">
<div class="box2">Text1</div>
<div class="box1 colorGreen">O</div>
</div>
I think following code snippet would help you to get your desired result
let box1 = document.querySelectorAll(".box1");
let box2 = document.querySelectorAll(".box2");
box1.forEach((b1,i) => {
b1.addEventListener("click",(ev) => {
ev.target.classList.toggle("colorGreen");
ev.target.classList.toggle("colorRed");
console.log(box2[i]);
if(ev.target.classList.contains("colorGreen")){
box2[i].textContent = "Text1";
}else{
box2[i].textContent = "Text2"
}
})
})

How can i make an image set a class to display:none and then set a specific id to display:inline

I'm trying to create a function that hides a class of divs then shows one of those divs by it's id. Here is what I have but I'm not sure if this is the right way to do it. If there is a better way I'm open to it, or if someone can identify an error in this code. What I would like is for the page to load with none of the bio classes visible, then when an image is clicked the bio with the corresponding id appears in its place. Searching only gave me this answer which did not help me. The code below has the bio class divs invisible when the page loads, the image can be clicked but the div does not appear on click. Hopefully this all makes sense.
.bio {
display: none;
}
#id1 {
display: none;
}
#id2 {
display: none;
}
<script language="JavaScript">
function setVisibility(name, id) {
document.getElementByClassName(name).style.display = "none";
document.getElementById(id).style.display = "inline";
}
</script>
<input type="image" src="name1_staff.jpg" onclick="setVisibility('bio', 'id1');" ;>
<input type="image" src="name2_staff.jpg" onclick="setVisibility('bio', 'id2');" ;>
<div class="bio" id="id1">
<h3>text</h3>
<p>more</p>
</div>
<div class="bio" id="id2">
<h3>text</h3>
<p>more</p>
It's wrong way I think. Let's do so:
function removeHidden(className)
{
var classes = className.split(' ');
var newClasses = [];
while (classes.length > 0) {
var name = classes.shift();
if (name != 'hidden' && newClasses.indexOf(name) < 0) {
newClasses.push(name);
}
}
return newClasses.join(' ');
}
function addHidden(className)
{
return removeHidden(className) + ' hidden';
}
function setVisibility(name, id)
{
var x = document.getElementsByClassName(name);
var i;
for (i = 0; i < x.length; i++) {
if (x[i].id == id) {
x[i].className = removeHidden(x[i].className);
} else {
x[i].className = addHidden(x[i].className);
}
}
}
setVisibility('bio', 'id1');
.bio {
/* don't put here display: none */
/* you can delete it if you have no other styles */
}
.hidden {
display: none;
}
<input type="image" src="http://www.hanselman.com/blog/content/binary/WindowsLiveWriter/Hans.NETMVCJeffAtwoodandhistechnicalteam_1349C/stackoverflow-logo-250_3.png" onclick="setVisibility('bio', 'id1');" ;>
<input type="image" src="http://www.hanselman.com/blog/content/binary/WindowsLiveWriter/Hans.NETMVCJeffAtwoodandhistechnicalteam_1349C/stackoverflow-logo-250_3.png" onclick="setVisibility('bio', 'id2');" ;>
<div class="bio" id="id1">
<h3>FIRST DESCRIPTION</h3>
<p>description description description description description</p>
</div>
<div class="bio" id="id2">
<h3>SECOND DESCRIPTION</h3>
<p>description description description description description</p>
</div>
Try this
<script type="text/javascript">
function setVisibility(name, id) {
var x = document.getElementsByClassName(name);
var i;
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
document.getElementById(id).style.display = "inline";
}
</script>
<input type="image" src="name1_staff.jpg" onclick="setVisibility('bio', 'id1');">
<input type="image" src="name2_staff.jpg" onclick="setVisibility('bio', 'id2');">
<div class="bio" id="id1">
<h3>text</h3>
<p>more</p>
</div>
<div class="bio" id="id2">
<h3>text</h3>
<p>more</p>
</div>
Try using the visibility property. In this case, you won't have to deal with your .bio container. You can simply focus on showing and hiding your content. See here.
Keep in mind: With your solution you're setting your containers are always visible. You may also attach a visible property to your container to not get a blank space (if you trigger your 2nd button first).

Make div in div clickable with Javascript

Have a problem and can't get to solve it. Tried to use QuerySelectorAll and comma separating with GetElementsByClassName, but that didn't work, so I am wondering how to solve this problem.
I have this HTML:
<div class="area">Test title
<div class="some content" style="display: none">blablbala
<input></input>
</div>
<div class="two">This should be clickable too</div>
</div>
<div class="area">
Test title
<div class="some content">
blablbala
<input></input>
</div>
<div class="two">This should be clickable too</div>
</div>
JS:
function areaCollapse() {
var next = this.querySelector(".content");
if (this.classList.contains("open")) {
next.style.display = "none";
this.classList.remove("open");
} else {
next.style.display = "block";
this.classList.add("open");
}
}
var classname = document.getElementsByClassName("area");
for (var i = 0; i < classname.length; i++) {
classname[i].addEventListener('click', areaCollapse, true);
}
http://jsfiddle.net/1BJK903/nb1ao39k/6/
CSS:
.two {
position: absolute;
top: 0;
}
So now, the div with classname "area" is clickable. I positioned the div with class "two" absolute and now the whole div is clickable, except where this other div is. If you click on the div with classname "two", it doesn't work (it does not collapse or open the contents). How can I make this work, without changing the structure?
One way is using a global handler, where you can handle more than one item by checking its id or class or some other property or attribute.
Below snippet finds the "area" div and pass it as a param to the areaCollapse function. It also check so it is only the two or the area div (colored lime/yellow) that was clicked before calling the areaCollapse.
Also the original code didn't have the "open" class already added to it (the second div group), which mean one need to click twice, so I change the areaCollapse function to check for the display property instead.
function areaCollapse(elem) {
var next = elem.querySelector(".content");
if (next.style.display != "none") {
next.style.display = "none";
} else {
next.style.display = "block";
}
}
window.addEventListener('click', function(e) {
//temp alert to check which element were clicked
//alert(e.target.className);
if (hasClass(e.target,"area")) {
areaCollapse(e.target);
} else {
//delete next line if all children are clickable
if (hasClass(e.target,"two")) {
var el = e.target;
while ((el = el.parentElement) && !hasClass(el,"area"));
if (targetInParent(e.target,el)) {
areaCollapse(el);
}
//delete next line if all children are clickable
}
}
});
function hasClass(elm,cln) {
return (" " + elm.className + " " ).indexOf( " "+cln+" " ) > -1;
}
function targetInParent(trg,pnt) {
return (trg === pnt) ? false : pnt.contains(trg);
}
.area {
background-color: lime;
}
.two {
background-color: yellow;
}
.area:hover, .two:hover {
background-color: green;
}
.some {
background-color: white;
}
.some:hover {
background-color: white;
}
<div class="area">Test title clickable 1
<div class="some content" style="display: none">blablbala NOT clickable 1
</div>
<div class="two">This should be clickable too 1</div>
</div>
<div class="area">Test title clickable 2
<div class="some content">blablbala NOT clickable 2
</div>
<div class="two">This should be clickable too 2</div>
</div>
<div class="other">This should NOT be clickable</div>
You need to find your two elements while you're binding classname, and bind that as well.
var classname = document.getElementsByClassName("area");
for(var i=0; i < classname.length; i++){
classname[i].addEventListener('click', areaCollapse, true);
var twoEl = classname[i].getElementsByClassName("two")[0];
twoEl.addEventListener('click', function(e) { console.log('two clicked'); });
}
If you want to use jQuery:
$('.two').click(function(){
//action here
});

Setting background color of div on click

I have a set of dynamically generated div elements like:
<div on-click="selected">one</div>
<div on-click="selected">two</div>
<div on-click="selected">three</div>
<div on-click="selected">four</div>
<div on-click="selected">five</div>
<div on-click="selected">six</div>
<div on-click="selected">seven</div>
I want to change the background color of div on which it is clicked and lose it when another div is clicked.
I could achieve this using tabindex, but I want to retain it until I click it on the another div or clear it intentionally, which tabindex does not provide.
How can I acieve it using javascript?
<div class="radiodiv" onclick=selected(this)>one</div>
<div class="radiodiv" onclick=selected(this)>two</div>
<div class="radiodiv" onclick=selected(this)>three</div>
<div class="radiodiv" onclick=selected(this)>four</div>
<div class="radiodiv" onclick=selected(this)>five</div>
<div class="radiodiv" onclick=selected(this)>six</div>
<div class="radiodiv" onclick=selected(this)>seven</div>
<script>
var divItems = document.getElementsByClassName("radiodiv");
function selected(item) {
this.clear();
item.style.backgroundColor = 'red';
}
function clear() {
for(var i=0; i < divItems.length; i++) {
var item = divItems[i];
item.style.backgroundColor = 'white';
}
}
</script>
Put all Your 'divs' into one div which will be container.
Then, by js, loop trough them and set css for non-selected and different for selected.
code :
function sel(id) {
var divs=document.getElementById('container').getElementsByTagName('div'); //get all divs from div called container
for(var i=0;i<divs.length; i++) {
if(divs[i]!=id) { //if not selected div set .items css
divs[i].className='items';
}
}
id.className='selitem'; //set different css for selected one
}
/* css for non-selected div*/
.items
{
display:block;
width:200px;
background-color:white;
color:black;
cursor:pointer;
margin-bottom:5px;
}
.items:hover
{
background-color:blue;
color:white;
}
/* css for selected div*/
.selitem
{
display:block;
width:200px;
background-color:red;
color:yellow;
cursor:pointer;
margin-bottom:5px;
}
<div id="container">
<div class="items" onclick="sel(this)">one</div>
<div class="items" onclick="sel(this)">one</div>
<div class="items" onclick="sel(this)">one</div>
<div class="items" onclick="sel(this)">one</div>
<div class="items" onclick="sel(this)">one</div>
<div class="items" onclick="sel(this)">one</div>
<div class="items" onclick="sel(this)">one</div>
</div>
There is explanation in the code.
Try this:
<div onclick="selected(this)">one</div>
<div onclick="selected(this)">two</div>
<div onclick="selected(this)">three</div>
<div onclick="selected(this)">four</div>
<div onclick="selected(this)">five</div>
<div onclick="selected(this)">six</div>
<div onclick="selected(this)">seven</div>
<script>
function selected(element)
{
var divs=document.getElementsByTagName("div");
divs.forEach(function(i)
{
i.style.backgroundColor="auto";
});
element.style.backgroundColor="red";
}
</script>
FYI, without any loops.
var xxx = null;
function sel(element){
if(xxx != null){
xxx.className = "default";
}
element.className = "selected";
xxx = element;
}
The best way to do that, is called a function in JavaScript, onclick or another. In this function you can create your own code, try to change the CSS properties and you will change the background color.
One example that I created:
function onoverbut(elemento)
{
elemento.style.color= "silver";
elemento.style.fontSize= "25px";
}
name function: onoverbut
attribute: elemento, which is the class or id html, that you need to pass.

Changing class of elements

I want to set up floating elements in a way it would depend of their amount.
<div id="whatever">
<div class="iwantthischangedto3elements">
element 1
element 2
element 3
</div>
<div class="iwantthischangedto2elements">
element 1
element 2
</div>
</div>
I can't really figure how to do this.
I'm guessing javascript is the answer, but can't get it work :
<script type="text/javascript">
function f() {
var list = document.getElementById("whatever");
var nbofelements = whatever.getElementsByTagName("a").length;
return nbofelements ;
whatever.getElementsByTagName("div").className += "elements + nbofelements";
}
</script>
Thanks for helping, I really struggle with javascript...
Edit:
Thanks all for your answers.
Sorry i didn't make myself clear enough, english isn't my first language.
Tambo did get what I meant, code works great.
However there's something I forgot...
An "h1" can be sometimes placed before the "a" list, and should not be counted as an element. Possibly other "h2", "h3", and so on... I want to count only "a" elements...
<div id="whatever">
<div class="iwantthischangedto3elements">
<h1>Do no not count this</h1>
element 1
element 2
element 3
</div>
Any idea how to proceed ?
Cheers
Vincent
You can use the for loop and Element.classList to add class
var whateverChild = document.querySelectorAll("#whatever div");
for(var i = 0; i < whateverChild.length; i++) {
//var anchor = document.querySelectorAll(whateverChild);
if(whateverChild[i].childElementCount == 2){
whateverChild[i].classList.add("two")
}else if(whateverChild[i].childElementCount == 3){
whateverChild[i].classList.add("three")
}
}
.two a{color: green}
.three a{color: red}
<div id="whatever">
<div class="iwantthischangedto3elements">
element 1
element 2
element 3
</div>
<div class="iwantthischangedto2elements">
element 1
element 2
</div>
</div>
If you have a paragraph in it you can use this
var whateverChild = document.querySelectorAll("#whatever div");
for(var i = 0; i < whateverChild.length; i++) {
var anchorLength = whateverChild[i].querySelectorAll("a").length;
if(anchorLength == 2){
whateverChild[i].classList.add("two")
}else if(anchorLength == 3){
whateverChild[i].classList.add("three")
}
}
.two a{color: green}
.three a{color: red}
<div id="whatever">
<div class="iwantthischangedto3elements">
element 1
<p> i am a paragraph </p>
element 2
element 3
</div>
<div class="iwantthischangedto2elements">
element 1
element 2
</div>
</div>
You can reduce the code to this
var numbersArray = ["zero", "one", "two", "three", "four", "five"],
whateverChild = document.querySelectorAll("#whatever div");
for(var i = 0; i < whateverChild.length; i++) {
var anchorLength = whateverChild[i].querySelectorAll("a").length;
whateverChild[i].classList.add(numbersArray[anchorLength])
}
.zero{color: orange}
.one{color: blue}
.two a{color: green}
.three a{color: red}
.four{color: purple}
.five{color: beige;}
<div id="whatever">
<div class="iwantthischangedto3elements">
element 1
<p> i am a paragraph </p>
element 2
element 3
</div>
<div class="iwantthischangedto2elements">
element 1
element 2
</div>
</div>

Categories

Resources