Changing class with Javascipt - javascript

Forgive me for my silly question, I'm a beginner :/
For some reason, I can't use Jquery due to some stuff with Divi theme on Wordpress.
I need to change CSS class to some links so that they will change color if selected
(these links reveals different divs contents)
I've tried this:
function linkcolor() {
document.getElementById(arguments[0]).className='serveminus';
for(var i=1; i< arguments.length-1; i++) {
document.getElementById(arguments[i]).className='serve';
}
}
When I call the function I'll add the anchors' ids as parameters.
The first one will be shown as "selected" (serveminus) one while the other will be grayed out (serve).
Somehow I've got this working but I need to have this other feature:
When a link is already selected and it has the "serveminus" class, if clicked again, the class changes back to "serve".
If I add the following condition I guess it generates a nonsense loop....
if (document.getElementById(arguments[0]).className='serveminus') {
document.getElementById(idlink).className='serve';
} else {

Sounds like you need to set an onClick event listener:
https://developer.mozilla.org/en-US/docs/Web/API/EventListener
Pseudo code might be:
if link is clicked and link is selected
set event listener on link
onClick change class to 'serve'
remove event listener

Sounds like you need an eventListener that will toggle the class, I would first have all the links that you want to apply this style to in an variable. And apply the code block below .
var linkArray = doucument.querySelectorAll('navigationLinks');
// Example-> var linkArray = document.querySelectorAll('nav ul li a');
for(var i = 0; i < linkArray.length; i++) {
linkArray[i].addEventListener("click", e => {
e.target.classList.toggle('classToToggle');
})
}

Related

Add querySelectorAll to add a class to a button

I'm having difficulty with using Javascript to add a class to a button.
Context: I have multiple cards in an instragram type format with a post and a "like" button. I want to add a class of card__like-button which changes the image to a filled heart but i remembered that querySelector only applies to the first element, instead i tried using querySelectorAll but now the code doesn't apply to anything.
First attemp:
// Controls for active like button
let likeButton = document.querySelector(".card__like-button");
// Event listener for like button click
likeButton.addEventListener("click", likeButtonClick);
// Add class on button click
function likeButtonClick() {
likeButton.classList.toggle("card__like-button_active");
}
Second attemp
// Controls for active like button
let likeButton = document.querySelectorAll(".card__like-button");
// Event listener for like button click
likeButton.addEventListener("click", likeButtonClick);
// Add class on button click
function likeButtonClick() {
likeButton.classList.toggle("card__like-button_active");
}
I created the following codepen to replicate the problem.
I've search on the site, w3schools documentation, etc. and can't seem to find what am I doing wrong.
Because of the document.querySelectorAll method will return an array of NodeList details see here, you cannot directly assign the addEventListener event to a list.
Instead, you have to loop through each element and assign events to it
document.querySelectorAll(".card__like-button").forEach(ele => {
ele.addEventListener("click", likeButtonClick);
});
// Add class on button click
function likeButtonClick() {
this.classList.toggle("card__like-button_active");
}
Try it :
let likeButtons = document.querySelectorAll(".card__like-button");
Array.from(likeButtons).forEach(ele => {
ele.addEventListener("click", likeButtonClick);
});
// Add class on button click
function likeButtonClick() {
this.classList.toggle("card__like-button_active");
}

Simplifying Active States

I have a question that I believe comes down to method preference.
In the following code when the div parent element is clicked on, the div itself expands and also triggers an icon animation
var slideSection6 = document.getElementById("manualsHandbooks").addEventListener("click", function()
{
if (this.parentElement.style.height == "60px" || this.parentElement.style.height == "")
{
this.parentElement.style.height = "215px";
document.getElementById("MAHB").classList.add("active");
}
else
{
this.parentElement.style.height = "60px";
document.getElementById("MAHB").classList.remove("active");
}
}, false);
I was thinking about how easy it was just to add a class and change the state of the icon and I wanted to experiment and try adding the another click event just to the icon to make it animate on a click and active the parent element in the div as well. Basically the reverse of the above.
I thought it would be as simple as adding another condition to the if statement to the effect of
|| document.getElementId("MAHB").classList.add=("active") == true
But this doesn't work and I know it's not proper form. Could someone get me started so I could figure this out?
Element.classList has a toggle method that could make things a bit easier. If you want to check if a certain class is present, you can also use classList.contains.
I'd suggest not using the height of your elements to determine their current state. Why don't you alter the height using an active css class?
Your click handler could then be:
var button = document.getElementById("manualsHandbooks");
button.addEventListener("click", function() {
this.parentElement.classList.toggle("active");
document.getElementById("MAHB").classList.toggle("active");
}, false);
You can read more about classList here: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

L.DomEvent.addListener() vs on(): why does one NOT work?

I created the following jquery script to cycle through each div in my HTML using a for loop. In this for loop, I define the the div and add a listener to it:
for (var i = 0; i < 3; i++) {
// Define listing
var listing = $('div[data-rid="' + i + '"]');
// Add listener to each listing div
// See below...
}
I have tried two different ways to add a listener. The first uses L.DomEvent.addListener() as such:
L.DomEvent.addListener(listing, 'mouseover', function(e) {
// Do stuff to listing div
}
The second uses the action mouseover():
listing.mouseover(function(e) {
// Do stuff to listing div
}
The L.DomEvent.addListener approach does not work. The mouseover approach works (i.e., it triggers for each div mouseover), but the "Do stuff to listing div" code only happens to the last listing div in the for loop. For example, I might mouseover div #1, but it "does stuff" div #3.
Does anyone have an idea how I might fix this issue?
Thanks!
Jesse
Try
L.DomEvent.addListener(listing[0], 'mouseover', function(e) {
// Do stuff to listing div
}
The case is, that the element jquery returns, is an array of the elements it found. listing[0] gets the first element in said array.

Url link shows upon drag, it should be hidden

I'm building a gallery in ReactJs and have draggable thumbs below main image.
The problem is, whenever I drag a thumb, its link url drags with the mouse.
http://prntscr.com/76kfrk
Is it possible to hide the url on drag?
Preferably using with Vanilla Js
Since it's the title of the a-tag (you didn't set an alt title, so it displays the url), you should be able to hide it with the following bit of Javascript:
var elements = document.getElementsByTagName('a');
for (var i = 0, len = elements.length; i < len; i++)
{
elements[i].removeAttribute('title');
}
This can be prevented with a preventDefault on the onMouseDown event.
//React Component
someFunc: function(e) {
e.preventDefault();
},
render: function() {
return (<img src="somepicture.jpg" onMouseDown={this.someFunc} />)
}
As pointed out below, the only way I know to prevent this is by calling event.preventDefault().
If you are using a special plugin for the slider then I would suggest you to take a look into its docs to see how you can receive the mousedown event when the user starts the drag.
This can also be prevented by using the CSS property -webkit-user-drag: none; for elements.

Writing this jQuery click function in JavaScript

I am slowly making my way from jQuery to vanilla JS, but I am struggling with wanting to write the following in JavaScript, would I have to setup a 'for' loop for each element? How would I target the child elements an an ID?
Here's what I would want to understand:
$('#id li').click(function(){
$(this).addClass('active');
});
I understand document getElementById to grab the '#id' but how would I achieve getting the child <li> elements? And how would I get the 'onclick' function to work for ANY list element clicked? Would I have to setup a 'for' loop for each element? Any help much appreciated!
Here is a JSFiddle that does what you want:
http://jsfiddle.net/digitalzebra/ZMXGC/10/
(function() {
var wrapper = document.getElementById("id");
var clickFunc = function(event) {
var target = event.originalTarget || event.target;
target.className = "active";
};
wrapper.addEventListener("click",clickFunc);
})();
A little bit of an explanation is in order...
First, I'm using a self executing function to fetch the wrapper div, using getElementById(). This is equivalent to using an id selector in jQuery: $('#id')
Next, I'm attaching a click handler to the element using the function addEventListener() and passing in an event type of click.
This binds the click handler function to the div element, the same as jQuery's click() would do. I'm using something called event bubbling, where a click event on any of the children of the wrapper will call the click handler attached to the wrapper.
Once the user clicks on the element, our function is called. originalTarget or target is the element that the user actually clicked in to, which in this case will always be an li. I'm then setting the class on that element to active.
Here is example for above question
http://jsfiddle.net/G3ADG/2/
(function() {
var id = document.getElementById("id");
var liele = id.getElementsByTagName("li");
for (var i = 0; i < liele.length; i++) {
liele[i].addEventListener("click", function () {
this.className = "active";
})
}
})();
Well I really liked Polaris878 solution as he is not using any loop inside it. In my solution first get HTML node information using document.getElementById this works similarly to $("#id"). than in next step I am fetching all tag type of "li" which are children of "id", than on this li tag array adding event listener to listen click functionality
className is one of attribute that allow to add class on that Node
I have tested above code in mozilla and chrome
This will work (IE >= 10), not want to search classList.add() replacement for IE<10,
var elems = document.querySelectorAll('#id li');
for (var i = 0; i < elems.length; i++) {
var elem=elems[i];
elem.addEventListener("click", function (e) {
this.classList.add('active');
});
}
fiddle

Categories

Resources