Upwards Transverse in Javascript DOM - javascript

I want to transverse upwards in javascript. like if i give input an element it will show all its parent elements till html tag but its not working like that. It only shows DIV,BODY,HTML.
function Transverse(p) {
var path = "";
var A = [];
var element = document.querySelector(document.getElementById(p).nodeName);
path = element.parentElement;
while (path) {
A.push(path);
path = path.parentElement;
}
console.log(A);
}
<div>
<button id="btn1" onclick="Transverse('btn1')">button 1</button>
<ul>
<button id="btn2" onclick="Transverse('btn2')">button 2</button>
<li>
<button id="btn3" onclick="Transverse('btn3')">button 3</button>
</li><br>
<section>
<a href="#">
<button id="btn4" onclick="Transverse('btn4')">button 4</button>
</a>
</section>
</ul>
<ol>
<li>
<h1>End of Page</h1>
<button id="btn5" onclick="Transverse('btn5')">Button 5</button>
</li>
</ol>
</div>

Thanks all it is working now ! I did the following Changes
function Transverse(p){
var A=[];
var element = document.getElementById(p);
var path=element.parentElement;
while(path){
A.push(path.nodeName);
path=path.parentElement;
}
console.log(A);
}

Related

Vanilla JS not(this)

I am looking for an easy and clean Vanilla JS solution for this jQuery code:
$(this).addClass('highlighted');
$('button').not(this).removeClass('highlighted');
When I click a specific button element, it should add the class 'highlighted', all the other button elements not(this) should have the highlighted class removed.
If your buttons have IDs, using them would be a good solution. Otherwise, you can simply filter the results from querySelectorAll:
Using ids:
function highlight(event) {
const target = event.target;
target.classList.add('highlighted');
document.querySelectorAll(`button:not(#${target.id})`).forEach(item => item.classList.remove('highlighted'));
}
.highlighted {
background: pink
}
<button id="btn1" onclick="highlight(event)">Button 1</button>
<button id="btn2" onclick="highlight(event)">Button 2</button>
<button id="btn3" onclick="highlight(event)">Button 3</button>
<button id="btn4" onclick="highlight(event)">Button 4</button>
Filtering the results:
function highlight(event) {
const target = event.target;
target.classList.add('highlighted');
Array.from(document.querySelectorAll(`button`)).filter(item => item != target).forEach(item => item.classList.remove('highlighted'));
}
.highlighted {
background: pink
}
<button onclick="highlight(event)">Button 1</button>
<button onclick="highlight(event)">Button 2</button>
<button onclick="highlight(event)">Button 3</button>
<button onclick="highlight(event)">Button 4</button>
If you remove the highlighted class from all buttons first, you can add it afterward to the only highlighted button.
const stripHighlighted = (button) => {
button.classList.remove("highlighted");
}
document.querySelectorAll("button").forEach(stripHighlighted);
this.classList.add("highlighted");

Display none if child and parent element have the same class

I have these menus around my horizontal scrolling site.
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section
The goal is to filter them based if the button classes have the same class as the ones in the section. If they have the same class (in this example 'fun-stuff') then that button will display:none.
My jQuery. I feel I'm close or totally over-complicating it.
jQuery(document).ready(function($) {
var theList = $('.nav-list button');
var i;
for (i=0; i < theList.length; i++){
var theButtons = '"' + theList[i].className + '"';
var parentClassName = theList[i].closest('section').className;
// tried this one. Was close i believe but no dice
if(theButtons = theList[i].closest('section').hasClass('"' + theButtons + '"') ){
// display that button as none
}
// tried this as well and for each button got 'no' in the console
if( $(theList[i].closest('section') ).hasClass(theButtons) ){
console.log('yes');
} else {
console.log ('no');
}
}
});
Yes you overdid it somewhat
$(function() {
$("button").each(function() {
var $parent = $(this).closest("section"), // the section wrapping the button
same = $parent.hasClass($(this).attr("class")); // parent has this button's class too
$(this).toggle(!same); // hide if the same (show if not)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
If you have more than one class on the button and you want to hide if one of them matches
$(function() {
$("button").each(function() {
var bList = this.classList,
parentList = $(this).closest("section")[0].classList, // the DOM element's classList
same = [...parentList] // convert to iterable
.filter(ele => bList.contains(ele)) // look up parent class in button classList
.length>0; // found?
$(this).toggle(!same);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff bla">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
You can turn the section classes into a regular array, then filter and hide the buttons.
jQuery(document).ready(function($) {
var classes = $('#slide-1').attr("class").split(/\s+/);
classes.forEach(function (cls) {
$('.nav-list button').filter('.' + cls).hide()
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
You can do this pretty easily with vanilla Javascript:
const classNames = document.getElementById("slide-1").classList;
document.querySelectorAll(".nav-list > button").forEach((el) => {
if(classNames.contains(el.classList)){
el.style.display = "none";
}
});
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
Edit: Done with two lines of code:
const classList = document.getElementById("slide-1").classList;
document.querySelectorAll(".nav-list > button").forEach(el => el.style.display = classList.contains(el.classList) ? "none": "initial");
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>

get the different values from button with same class name

I want to get the values from clicking the button with same class name, but whenever I clicked the button it shows undefined.
var clr;
const btn = document.querySelectorAll('.color');
function myFunction() {
for (var i = 0; i < btn.length; i++) {
clr = btn[i].value;
console.log(clr);
}
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction()"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction()"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction()"> Purple </button>
</div>
const btn = document.querySelectorAll('.color'); gets the div not the buttons. Change that to const btn = document.querySelectorAll('.btn');:
var clr;
const btn = document.querySelectorAll('.btn');
function myFunction() {
for (var i = 0; i < btn.length; i++) {
clr = btn[i].value;
console.log(clr);
}
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction()"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction()"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction()"> Purple </button>
</div>
If you only want the value from the button being clicked, then change your code to
function myFunction(btn) {
console.log(btn.value);
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction(this)"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction(this)"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction(this)"> Purple </button>
</div>
do it in this way it will give you exact result
function myFunction(event) {
clr = event.target.value;
console.log(clr);
}
<div class="color">
<button class="btn" value="#BADA55" onclick="myFunction(event)"> Yellow </button>
<button class="btn" value="#10A426" onclick="myFunction(event)"> Green </button>
<button class="btn" value="#8787DE" onclick="myFunction(event)"> Purple </button>
</div>
First: scripting where scripting should be (no inline handlers). So add an event listener to the document, and let it check if the target (the element clicked) has classname btn. In that case: iterate through the an Array of elements with className btn (Array.from(document.querySelectorAll(".btn"))) using Array.forEach to display the values of those elements.
document.addEventListener("click", myFunction);
function myFunction(evt) {
console.clear();
if (evt.target.classList.contains("btn")) {
// a button.btn was clicked, so
let report = `You clicked button with value ${evt.target.value}. Other .btn values:`;
let values = [];
Array.from(document.querySelectorAll(".btn"))
.forEach(val => val !== evt.target && values.push(val.value));
console.log(`${report} ${values.join(", ")}`);
}
}
<div class="color">
<button class="btn" value="#BADA55"> Yellow </button>
<button class="btn" value="#10A426"> Green </button>
<button class="btn" value="#8787DE"> Purple </button>
</div>

JS get value of buttons in a dynamic grid

Squares = Buttons with x = clicked, x = value
How do I create a textarea value onClick on a button that contains the value of each square AND empty values of anything that is not selected,
i.e.
<textarea>x,&bnsp;,&bnsp; ,&bnsp;\n,&bnsp;x,&bnsp; ,&bnsp;\n etc.</textarea>
Basically the text output needs to reflect the values of the squares in plain text, that’s why I need empty values to create that “visual”.
The rows and squares in each row are also subject to being dynamically generated when the page loads, based on a default or changed value.
Thank you!
It requires a bit of jQuery, but this does what you want.
var result = [];
var idnum;
for (var i = 1; i < 10; i++) {
result.push($("#" + i).html() + ",");
}
$(".result").html(result);
$(".button").click(function() {
idnum = $(this).attr("id");
$(this).html("x");
result[idnum - 1] = "x,";
$(".result").html(result);
});
.button {
width: 50px;
height: 50px;
vertical-align: top;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button" id="1"> </button>
<button class="button" id="2"> </button>
<button class="button" id="3"> </button>
<br>
<button class="button" id="4"> </button>
<button class="button" id="5"> </button>
<button class="button" id="6"> </button>
<br>
<button class="button" id="7"> </button>
<button class="button" id="8"> </button>
<button class="button" id="9"> </button>
<br><br>
<textarea class="result">Result</textarea>

First To-do-list with querySelectorAll [duplicate]

This question already has answers here:
Adding click event listener to elements with the same class
(5 answers)
Closed 4 years ago.
I have some problems with querySelectorAll. Script is working only with querySelector, but it deletes only first li. When I try to replace querySelector with querySelectorAll to make all delete buttons work there is error - "deleteButton.addEventListener is not a function".
html:
body>
<div id="buttons">
<input type="text" placeholder="twoje zadanie...">
<button type="submit" class="add">dodaj</button>
</div>
<div id="tasks">
<ul>
<li><button class="done">done</button>
asd
<button class="delete">x</button></li>
<li>
<button class="done">done</button>
asdd
<button class="delete">x</button></li>
<li>
<button class="done">done</button>
dsad
<button class="delete">x</button></li>
</ul>
</div>
<script src="script.js"></script>
</body>
js:
var deleteButton = document.querySelectorAll('.delete');
deleteButton.addEventListener('click', function() {
var li = document.querySelector('li');
li.classList.add('li-delete');
});
Reason: Coz querySelectorAll get you the list of matching nodes. And there is no .addEve.. property that you can use on list.
Moreover, document.querySelector('.delete'); will get you the first button and will only add listener to the this button but you don't want.
If you want to add listeners to all of the elements you should loop through the list and add a listener on all of the matched elements. Like
var el = document.querySelectorAll('.delete');
for(var i=0; i<el.length; i++){
el[i].addEventListener('click', function(){
console.log("clicked");
var li = this.parentNode;
li.classList.add('li-delete');
})
}
.li-delete{
color : red;
}
<div id="tasks">
<ul>
<li><button class="done">done</button>
asd
<button class="delete">x</button></li>
<li>
<button class="done">done</button>
asdd
<button class="delete">x</button></li>
<li>
<button class="done">done</button>
dsad
<button class="delete">x</button></li>
</ul>
</div>
addEventListener on NodeList
You have to iterate through each node and attach the event listener if you want to use .querySelectorAll to select your elements.
It looks like you might be new to working with the DOM in JavaScript. If that's the case, I'd recommend taking a look at jQuery. It's not a lightweight library, but it makes many of these things much easier.
2 Problens in your code.
First querySelectorAll will return an array of all the elements that match the query. I added a console.log(deleteButtons), so you can see what thequerySelectorAll`` is generating. You will need a loop to add the event listener to each of the elements in the array.
Second, you can use this to get the button that trigger the event and then go get their parent <li> using the js .parentNode
Hope this helps :)
var deleteButton = document.querySelectorAll('.delete');
console.log(deleteButton);
for(let i=0; i<deleteButton.length;i++){
deleteButton[i].addEventListener('click', function() {
var li = this.parentNode;
li.classList.add('li-delete');
})
};
.li-delete {display:none;}
<div id="buttons">
<input type="text" placeholder="twoje zadanie...">
<button type="submit" class="add">dodaj</button>
</div>
<div id="tasks">
<ul>
<li><button class="done">done</button>
asd
<button class="delete">x</button></li>
<li>
<button class="done">done</button>
asdd
<button class="delete">x</button></li>
<li>
<button class="done">done</button>
dsad
<button class="delete">x</button></li>
</ul>
</div>
<script src="script.js"></script>

Categories

Resources