Vanilla JS not(this) - javascript

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");

Related

Change div HTML content with attribute from button on click

I have some data attributes on buttons that I need to send as content to a div when those buttons are clicked. A part of my code until now is this:
function getDiscount() {
var buttons = document.querySelectorAll(".form-button");
buttons.forEach(function(item, index) {
item.addEventListener('click', function() {
var discount = getDiscount(this);
});
});
function getDiscount(clicked_element) {
var val = clicked_element.getAttribute("data-discount");
return val;
}
};
<div class="discount__Topics">
<div><strong class="discount-amount">50</strong>%</div>
<div class="offers">
<button class="form-button" data-discount="38">Offer 1</button>
<button class="form-button" data-discount="50">Offer 2</button>
<button class="form-button" data-discount="22">Offer 3</button>
<button class="form-button" data-discount="88">Offer 4</button>
</div>
</div>
<div class="discount__Topics">
<div><strong class="discount-amount">60</strong>%</div>
<div class="offers">
<button class="form-button" data-discount="12">Offer 1</button>
<button class="form-button" data-discount="32">Offer 2</button>
<button class="form-button" data-discount="44">Offer 3</button>
<button class="form-button" data-discount="55">Offer 4</button>
</div>
</div>
I'm just not seeing how to change the html with attribute when it's clicked and how to have two sets of buttons or more on the same page.
Hope someone can help.
Many thanks
UPDATE: Now the code is running properly but im having troubles with getting multiples div's with multiple buttons working. I've created a for.Each wic logs my div correctly but im not beeing able to have the working properly.
var discounters = document.querySelectorAll(".discount__Topics");
discounters.forEach((index) => {
console.log(index)
var buttons = document.querySelectorAll(".form-button");
buttons.forEach(function (item) {
item.addEventListener('click', function(){
var discount = getDiscount(this);
let span = document.querySelector('.discount-amount')
span.innerHTML = '<strong>' + discount+ '</strong>'
});
});
function getDiscount(clicked_element) {
var val = clicked_element.getAttribute("data-discount");
return val;
}
});
<div class="discount__Topics">
<div><strong class="discount-amount">38</strong>%</div>
<div class="offers">
<button class="form-button" data-discount="38">Offer 1</button>
<button class="form-button" data-discount="50">Offer 2</button>
<button class="form-button" data-discount="22">Offer 3</button>
<button class="form-button" data-discount="88">Offer 4</button>
</div>
</div>
<div class="discount__Topics">
<div><strong class="discount-amount">12</strong>%</div>
<div class="offers">
<button class="form-button" data-discount="12">Offer 1</button>
<button class="form-button" data-discount="32">Offer 2</button>
<button class="form-button" data-discount="44">Offer 3</button>
<button class="form-button" data-discount="55">Offer 4</button>
</div>
</div>
You have defined two functions called getDiscount, it would be better to let them have different name
function init(){
var buttons = document.querySelectorAll(".form-button");
buttons.forEach(function (item, index) {
item.addEventListener('click', function(){
var discount = getDiscount(this);
let span = document.querySelector('.discount-amount')
span.innerHTML = '<strong>' + discount+ '</strong>%'
//span.innerHTML =discount.bold()+ '%' // we can use bold() instead
});
});
function getDiscount(clicked_element) {
var val = clicked_element.getAttribute("data-discount");
return val;
}
};
init()
<div><span class="discount-amount"><strong>55</strong>%</div>
<div class="offers">
<button class="form-button" data-discount="38">Offer 1</button>
<button class="form-button" data-discount="50">Offer 2</button>
<button class="form-button" data-discount="22">Offer 3</button>
<button class="form-button" data-discount="88">Offer 4</button>
</div>
Update:
for your updated question,since it has multiple button groups and divs,so we need to sepereate them correctly.
One solution is to using index,change
let span = document.querySelector('.discount-amount')
to
let span = document.querySelectorAll('.discount-amount')[Math.floor(index/4)]
In my opinios,the best way is to let them have different id or class,so that we can query them easily.
function init(){
var buttons = document.querySelectorAll(".form-button");
buttons.forEach(function (item, index) {
item.addEventListener('click', function(){
var discount = getDiscount(this);
let span = document.querySelectorAll('.discount-amount')[Math.floor(index/4)]
span.innerHTML = '<strong>' + discount+ '</strong>%'
//span.innerHTML =discount.bold()+ '%' // we can use bold() instead
});
});
function getDiscount(clicked_element) {
var val = clicked_element.getAttribute("data-discount");
return val;
}
};
init()
<div class="discount__Topics">
<div><strong class="discount-amount">50</strong>%</div>
<div class="offers">
<button class="form-button" data-discount="38">Offer 1</button>
<button class="form-button" data-discount="50">Offer 2</button>
<button class="form-button" data-discount="22">Offer 3</button>
<button class="form-button" data-discount="88">Offer 4</button>
</div>
</div>
<div class="discount__Topics">
<div><strong class="discount-amount">60</strong>%</div>
<div class="offers">
<button class="form-button" data-discount="12">Offer 1</button>
<button class="form-button" data-discount="32">Offer 2</button>
<button class="form-button" data-discount="44">Offer 3</button>
<button class="form-button" data-discount="55">Offer 4</button>
</div>
</div>
If I understand your question correctly, you are looking for something like this.
var buttons = document.querySelectorAll(".form-button");
var discountRef = document.querySelector(".discount-amount");
function setDiscount(pointerEvent) {
// get the clicked button from the pointerEvent
var discount = pointerEvent.target.dataset.discount
// add the discount to <span class="discount-amount"></span>
discountRef.innerText = discount
}
buttons.forEach(function (item) {
item.addEventListener('click', setDiscount);
});
Let me know if this helped you out!

How to detect whether 2 buttons are clicked one after the another in javascript?

I've to trigger an alert when button #1 is clicked and then after the button 2# is clicked
if button 1# is clicked and immediately user is clicked on another button button x# then alert should not be trigger.
I've to track those 2 clicks that are one after the other so that i'll embed the js script in the google tag manager
This example will trigger an alert when Button 3 is clicked after Button 1.
var Last;
function getLast(t){
if(Last=='btn1'&&t.id=='btn3')alert('btn1 then btn3')
Last=t.id;
};
<button id='btn1' onclick='getLast(this);'>Button 1</button>
<button id='btn2' onclick='getLast(this);'>Button 2</button>
<button id='btn3' onclick='getLast(this);'>Button 3</button>
EDIT: with a timeout (like sugsested on comments), sequence must be done before 2 sec.
var Last,time;
function getLast(t){
if(Last=='btn1'&&t.id=='btn3')alert('btn1 then btn3');
Last=t.id;
clearTimeout(time);
time=setTimeout(function(){Last='';}, 2000);
};
<button id='btn1' onclick='getLast(this);'>Button 1</button>
<button id='btn2' onclick='getLast(this);'>Button 2</button>
<button id='btn3' onclick='getLast(this);'>Button 3</button>

Upwards Transverse in Javascript DOM

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);
}

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>

How to know the button pressed among buttons in the div in Javascript

I have a div of 4 buttons, when I click on any button it redirects to the same page for all the buttons, I want to know which button the user has pressed before going to the next page, I've been trying, but couldn't find that.
Here is my code :
$( "#buttons" ).click(function() {
alert('button');
window.location.href = "score.html";
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="countdown"></p>
<div id="buttons">
<button type="button" id="button1">button 1</button>
<button type="button" id="button2">button 2</button>
<button type="button" id="button3">button 3</button>
<button type="button" id="button4">button 4</button>
</div>
Do you have any idea
The element that the click started in is available as target on the event object passed into your handler, so (but see more below):
// Accept the event arg -------v
$( "#buttons" ).click(function(e) {
alert('button: ' + e.target.id); // <=== Use e.target.id to get its ID
// window.location.href = "score.html"; (commented out for live demo)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="countdown"></p>
<div id="buttons">
<button type="button" id="button1">button 1</button>
<button type="button" id="button2">button 2</button>
<button type="button" id="button3">button 3</button>
<button type="button" id="button4">button 4</button>
</div>
Note that that will do the alert whenever there's a click inside the #buttons div, even if it's not on a button. If you only want clicks on the buttons, you can use a selector with .on to only call you when the click went through a button. It will call your handler as though you had hooked the handler directly to the buttons, even though in fact you've hooked it to the #button div, and so we use this.id for the ID:
$( "#buttons" ).on("click", "button", function() {
alert('button: ' + this.id);
// window.location.href = "score.html"; (commented out for live demo)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="countdown"></p>
<div id="buttons">
<button type="button" id="button1">button 1</button>
<button type="button" id="button2">button 2</button>
<button type="button" id="button3">button 3</button>
<button type="button" id="button4">button 4</button>
</div>

Categories

Resources