How to add class with JS - javascript

I have this code:
let link = document.querySelectorAll(".menu-left p a");
for (var i =0;i<link.length;i++){
link[i].addEventListener("click", function () {
this.classList.add('clicked')
})
}
I click on a link and I add "clicked" class on <a> tag. My issue is: when I click on the next link I want to remove de previous class, but this now doesn't happen. How to do this? What changes should I add in my code for getting the result?

Save a reference to the previously clicked element, and if it exists, remove the class:
const links = document.querySelectorAll(".menu-left p a");
let lastLink;
for (let i = 0; i<links.length; i++){
links[i].addEventListener("click", function () {
if (lastLink) {
lastLink.classList.remove('clicked');
}
this.classList.add('clicked');
lastLink = this;
})
}
(note that because links is a collection, not a single element, it would probably make more sense to call it links, plural)

let link = document.querySelectorAll(".menu-left p a");
for (var i =0;i<link.length;i++){
link[i].addEventListener("click", function (e) {
e.target.classList.toggle('clicked')
})
}

You could take a functional approach to remove any elements with the clicked class before setting the next link to clicked.
const links = document.querySelectorAll(".menu-left p a");
function clickedLinks() {
return document.querySelectorAll(".clicked");
};
for (let i = 0; i < links.length; i++) {
links[i].addEventListener("click", function () {
clickedLinks().forEach(function(link) {
link.classList.remove('clicked')
});
this.classList.add('clicked');
})
}
Alternative using forEach() in place of the for loop and es6 arrow functions.
const rmClickedClass = () => (
document.querySelectorAll(".clicked").forEach(
(link) => link.classList.remove('clicked')
)
);
document.querySelectorAll(".menu-left p a").forEach((link) => {
link.addEventListener("click", () => {
rmClickedClass();
link.classList.add('clicked');
});
};

Related

how i can use toggle and function that remove the class from the previous element together only using JavaScript i have tried to Different ways?

-First Way-
Here I Can't Remove The Previous Elements and add the class for The new One
linksBtnArr.forEach((item, index) => {
item.addEventListener("click", () => {
arrowArr[index].classList.toggle("active");
if (arrowArr[index].classList.contains("active")) {
menuArr[index].style.display = "block";
} else {
menuArr[index].style.display = "none";
}
});
});
-Second Way-
Here I Can remove The previous Element But i Can't use Toggle to Remove The class Form The Same Element That i clicked again
linksBtnArr.forEach((link, i) => {
link.addEventListener("click", () => {
removeActiveClasses();
arrowArr[i].classList.add("active");
});
});
// Remove The previous Menu
function removeActiveClasses() {
arrowArr.forEach((arrow) => {
arrow.classList.remove("active");
});
}
this way
linksBtnArr.forEach( (lk,_,All_lk) => {
lk.onclick =_=> {
if (lk.classList.toggle('active'))
All_lk.forEach( lx=> lx.classList.toggle('active', lk===lx) )
} })
Look At The UL Links That what i'm trying to Do !
https://mohmostafa-web.github.io/blogr-landing-page-frontend-mentor

Using JS to apply CSS when clicking buttons

I am using a modal that when clicked it should popup full screen.
Everything is good, modal pops full screen but the header ( logo + menu ) still shows up.
I'm trying to use JS, so when the modal is clicked i want to apply a z-index to the header and when the close button is clicked i will apply another z-index to fix the header.
the link to be clicked is this:
<a class="vPlay vPlay-btn clickformodal" href="#modal-our-work-1" data-toggle="modal" data-video="241737557"><img src="/wp-content/uploads/2018/04/play1.png" /></a>
Now the JS code is this:
let open = document.selectElementByClassName("clickformodal");
let header = document.selectElementByClassName("mk-header");
let close = document.selectElementByClassName("close");
open.addEventListener('click', function () {
header.classList.add("headerbefore");
});
close.addEventListener('click', function () {
header.classList.remove("headerafter");
});
And this is the css that will be applied:
.headerbefore {
z-index: 1;
}
.headerafter {
z-index: 301;
}
The issue here appart that it's not doing what it is supposed too, google chrome shows an error in console saying that let open = document.selectElementByClassName("clickformodal"); is not a function.
What am i doing wrong here?
Help me out please, it's been 2 days that i'm trying to fix this and nothing till now :/
Thanks!!!
There are 2 things going wrong here:
it should be getElementsByClassName, not selectElementByClassName
as getElementsByClassName returns an element collection, you need to add [0] at its end, e.g. document.getElementsByClassName("clickformodal")[0]
let open = document.getElementsByClassName("clickformodal")[0];
let header = document.getElementsByClassName("mk-header")[0];
let close = document.getElementsByClassName("close")[0];
open.addEventListener('click', function () {
header.classList.add("headerbefore");
});
close.addEventListener('click', function () {
header.classList.remove("headerafter");
});
An option could be to use querySelector() instead
let open = document.querySelector(".clickformodal");
let header = document.querySelector(".mk-header");
let close = document.querySelector(".close");
open.addEventListener('click', function () {
header.classList.add("headerbefore");
});
close.addEventListener('click', function () {
header.classList.remove("headerafter");
});
If to add to more than 1, use querySelectorAll() (this sample assume there is as many open as close but only 1 header)
let open = document.querySelectorAll(".clickformodal");
let header = document.querySelector(".mk-header");
let close = document.querySelectorAll(".close");
for (var i = 0; i < open.length; i++) {
open[i].addEventListener('click', function () {
header.classList.add("headerbefore");
});
}
for (var j=0; j < close.length; j++) {
close[j].addEventListener('click', function () {
header.classList.remove("headerbefore");
});
}

Javascript Dynamically invoke shortcut keys combination function to shortcutjs plugin

Am getting key Combination from the server. Based on that am assigning key Combination to function dynamically. The below code is working for last iteration in loop. how below code is work for all iterations.
In my page i have two buttons save and cancel the below code is working for last iteration in for loop, It means btnCanel button triggers if i press key for save function.Any suggestions. hope understand my question.
$(document).ready(function fn() {
var keyCombination = new Object();
keyCombination['btnAdd'] = "Alt+S";
keyCombination['btnCancel'] = "Alt+C";
for (var k in keyCombination) {
if (keyCombination.hasOwnProperty(k)) {
shortcut.add(String(keyCombination[k]), function () {
var btnAdd = document.getElementById(String(k));
btnAdd.focus();
btnAdd.click();
});
}
}
});
if i give like this means it is working
shortcut.add("Alt+S", function () {
var btnAdd = document.getElementById('btnAdd ');
btnAdd .focus();
btnAdd .click();
});
shortcut.add("Alt+C", function () {
var btnCancel = document.getElementById('btnCancel');
btnCancel.focus();
btnCancel.click();
});
but if i try to add dynamically its overriding help me this issue.
Thanks in Advance.
I created a separate function outside the document.ready function like this now its working fine.
$(document).ready(function fn() {
var keyCombination = new Object();
keyCombination['btnAdd'] = "Alt+S";
keyCombination['btnCancel'] = "Alt+C";
for (var k in keyCombination) {
if (keyCombination.hasOwnProperty(k)) {
Set_KeyCombinations(k, keyCombination);
}
}
});
function Set_KeyCombinations(k, keyCombination) {
shortcut.add(String(keyCombination[k]), function () {
var eleId = document.getElementById(String(k));
if (eleId) {
if ($('#' + String(k).trim()).css('display') !== 'none' && eleId.getAttribute("disabled") !== "disabled") {
eleId.click();
eleId.focus();
}
}
});
}
Try this:
var keyCombinations = [ "Ctrl+Shift+X" , "Ctrl+Shift+Y" ];
for(var i=0; i<keyCombinations.length; i++){
(function(shorcutCombination){
shortcut.add(shorcutCombination,function() {
alert("i am " + shorcutCombination);
});
})(keyCombinations[i]);
}
The idea is that you need to preserve the value of keyCombinations[i]
as i increases in the loop. Tested this here: Openjs

Click a link with href attribute and execute the Javascript function

My script contains a link a element with href attribute of "#login" as below.
Login
I want to my Javascript function detect the "href" element in the link and execute. How can I do this? My Javascript function is
window.onload = function() {
document.getElementsByTagName("a[href=#login]").onclick = function(e) {
e.preventDefault();
alert("working");
}
}
Why have I seen no querySelector love in these answers?
If you want to use that CSS selector to grab your link, nothing is stopping you:
window.onload = function() {
document.querySelector("a[href='#login']").onclick = function(e) {
e.preventDefault();
alert("working");
}
}
Login
EDIT:
I saw in another answer that you believe there may be multiple links on a page that match that selector, in which case you'll need to loop through them:
window.onload = function() {
var links = document.querySelectorAll("a[href='#login']"),
//always create anonymous functions outside of a loop :)
click = function(e) {
e.preventDefault();
alert("working");
}, i;
for (i = 0; i < links.length; i++) {
links[i].onclick = click;
}
}
Login
Login
Try this:
Login
function getValue()
{
alert("working");
e.preventDefault();
}
FIDDLE
Your getElementsByTagName is treating it like a jquery selector, which it is not designed to do.
It would be much simpler to give the tag an id and use getElementById:
window.onload = function() {
document.getElementById("loginLink").onclick = function(e) {
e.preventDefault();
alert("working");
}
}
Login
If for whatever reason you cannot change the html and you want to do it this way you would need to get all a tags then loop through each one to test the href attribute. Note you need to use a.getAttribute("href") to get "#login", rather than just a.href which oftens give you an full URL:
window.onload = function() {
var aTags = document.getElementsByTagName("a");
for(var i = 0; i < aTags.length; i++) {
var a = aTags[i];
if(a.getAttribute("href") == "#login") {
a.onclick = function(e) {
e.preventDefault();
alert("working");
}
}
}
}
Login
Test
Login Again

JS - Show one FAQ at a time, hide others

FAQ fiddle
JS code:
var $ = function (id) {
return document.getElementById(id);
};
var faqs = $("faqs");
var h2Elements = faqs.getElementsByTagName("h2");
var h2Node;
for (var i = 0; i < h2Elements.length; i++) {
h2Node = h2Elements[i];
}
$("first_link").focus();
$(document).ready(function () {
$("h2").click(function () {
if (h2.hasAttribute("class")) {
h2.removeAttribute("class");
} else {
h2.setAttribute("class", "minus");
}
if (h2.nextElementSibling.hasAttribute("class")) {
h2.nextElementSibling.removeAttribute("class");
} else {
h2.nextElementSibling.hide();
}
});
});
Upon clicking a question, that answer should show. When I click on a different question, all other answers should retract (be hidden). I tweaked it a few times and either the code wouldn't hide anything (all answers still open) or all answers wouldn't open at all.
Starting from $(document).ready(function () {, how do I get the question to open one at a time when clicked (close others)?
Any input would be much appreciated!
create a function to hide all other div's having class name open, like:
function hideOthers() {
var othersDivEle = document.getElementsByClassName("open");
for(var d = 0; d < othersDivEle.length; d++) {
othersDivEle[d].removeAttribute("class");
}
}
and change your code in :
...
} else {
hideOthers();
h2.nextElementSibling.setAttribute("class", "open");
}
to
..
} else {
hideOthers();
h2.nextElementSibling.setAttribute("class", "open");
}
Updated jsFiddle

Categories