I have an event in which I need to add a class to an element with a matching class name.
For example:
<a class="one"></div>
<a class="two"></div>
<div class="one"></div>
<div class="two"></div>
How do I find and add an additional class to the element with the matching class name?
Here is my script, I need it to target the tag with matching class.
jQuery('div.two').waypoint(function(direction) {
if (direction === 'down') {
jQuery(this).addClass("active") // to <a> element that shares same class
}
else {
}
});
I'm not familiar with this plugin but I'll give it a shot. Based off what you've provided I think your problem is:
jQuery(this).addClass("active")
Since you already know the class, just do:
var tempClass = $(this).attr("class");
jQuery("a."+tempClass).addClass("active");
Just select by class names.
Array.prototype.forEach.call(document.querySelectorAll(".one"), function(el) {
el.classList.add("whateverClass");
});
Instead of a for loop, this uses the prototype method forEach with the call method to turn the NodeList into an array list, adding the class to each element with the class "one"
DEMO
You probably want to remove the class from the others first, then add to the applicable <a>
jQuery('div.two').waypoint(function(direction) {
if (direction === 'down') {
/* remove prior active class */
jQuery("a.active").removeClass('active');
/* add to current one */
jQuery("a.two").addClass('active');
}
else {
}
});
To make this more generic I would add a class like waypoint to all the content elements as well as a data-point to be able to simplify instances.
<div data-point="one" class="waypoint"></div>
JS
jQuery('.waypoint').waypoint(function(direction) {
if (direction === 'down') {
/* remove prior active class */
jQuery("a.active").removeClass('active');
/* add to current one */
var linkClass=$(this).data('point')
jQuery("a." + linkClass).addClass('active');
}
else {
}
});
Related
Which one of the following should be preferred under what circumstances?
btnElement.classList.add('btn');
btnElement.className = 'btn';
Using "classList", you can add or remove a class without affecting any
others the element may have. But if you assign "className", it will
wipe out any existing classes while adding the new one (or if you
assign an empty string it will wipe out all of them).
Assigning "className" can be a convenience for cases where you are
certain no other classes will be used on the element, but I would
normally use the "classList" methods exclusively.
And "classList" also has handy "toggle" and "replace" methods.
https://teamtreehouse.com/community/difference-between-classlist-and-classname
ClassList as the name suggest is the list of classes in an element.
If you have multiple classes on an element and you want to add/remove one without altering the rest you should use classList.
classList also provides methods like toggle which are really useful.
function toggleClass(){
let txt = document.querySelector("h2");
txt.classList.toggle("changebg");
}
.font-style {
font-family: sans-serif;
}
.changebg {
background-color: lightcoral;
}
<h2 class="font-style" >Hello World!</h2>
<button onclick='toggleClass()'>Toggle Background Class</button>
Using "classList", you can add or remove a class without affecting any others the element may have. But if you assign "className", it will wipe out any existing classes while adding the new one (or if you assign an empty string it will wipe out all of them)
classList
Using classList, you can add or remove a class without affecting any other classes the element may have.
So this is helpful for adding additional classes to an element that contain other classes.
classList has some handy methods like toggle and replace.
if (clicked) {
button.classList.add('clicked');
} else {
button.classList.remove('clicked');
}
Here if the button was clicked it will add the clicked class along with other classes the element may have and it will remove only the clicked class from the element.
className
If you use className, it will wipe out any existing classes while adding the new one (or if you assign an empty string it will wipe out all of them).
Using className can be convenience when you know this element will not use any other classes.
if (clicked) {
button.className = 'clicked';
} else {
button.className = '';
}
In this case, className will wipe all the classes the element may have and add clicked class to it. The empty string('') will wipe all the classes.
Conclusion
the recommendation would be to use className whenever possible.
Use classList when you need classList methods like toggle, replace, etc.
context https://dev.to/microrony/difference-between-classlist-and-classname-45j7
You can see the changes in JavaScript to apply same difference one with use of classList and other with className .
It will be clear from 1st btn only that classList add extra name in class while className replaces the whole class (only .border is applied) .
Further are different function of classList which cannot be achieved by className and at last 4 line of code is reduced to 1 liner with use of toggle .
So you should look to your needs : Like, if you want to completely replace the class property names than use className else you can use classList property with different methods .add() .remove() .replace() .toggle() to only have changes in specific without hampering all names of class
Instruction for below snippet : Reload the snippet when you click one button so that clear differences can be seen on next btns
var classList1 = document.getElementById("part1")
var classname2 = document.getElementById("part2")
function funcAdd() {
classList1.classList.add("border");
classname2.className = "border";
}
function funcRemove() {
classList1.classList.remove("color");
classname2.style.color = "black";
}
function funcReplace() {
classList1.classList.replace("background", "background1");
classname2.style.backgroundColor = "lightgreen";
}
function funcToggle() {
classList1.classList.toggle("color1");
if (classname2.style.color == "gold") {
classname2.style.color = "blue";
} else {
classname2.style.color = "gold";
}
}
.background {
background-color: red
}
.background1 {
background-color: lightgreen
}
.color {
color: blue
}
.font {
font-size: 24px;
}
.border {
border: 10px solid black
}
.color1 {
color: gold;
}
<div id="part1" class="background color font">classList</div>
<br><br><br>
<div id="part2" class="background color font">className</div>
<br><br><br>
<button onclick="funcAdd()">Add a border class</button>
<button onclick="funcRemove()">Remove a color class</button>
<button onclick="funcReplace()">Replace a background class</button>
<button onclick="funcToggle()">Toggle a color class</button>
<br><br>
I have just known one thing difference between className and classList. className returns string within they are names of the current element and classList also returns names but as an array.
I am wrapping the class; slideVisible to the first 3 blog articles displayed. This class removes the css property; display - none. I have added some indicators with the class; carousel-buttons, which also is based on the number of loops of sets of 3 blog posts. On click of these carousel-buttons I would like to remove the class slideVisible from the element which currently has it, and then add to the next element in the sequence.
I have used an index-related selector to demonstrate a way of creating this function, however this is not dynamic. How would I do this correctly?
jQuery(document).ready(function() {
var carosuelPost = jQuery(".post-slider-mango .post");
jQuery('.post-slider-mango .fusion-posts-container').wrapAll('<div id="dog-slider"><div class="carousel-inner"></div></div>');
for (var i = 0; i < carosuelPost.length; i += 3) {
let activeClass = '';
if(i == 0) activeClass = 'slideVisible';
carosuelPost.slice(i, i + 3).wrapAll('<div class="slideElements ' + activeClass + '"> </div>');
}
for (var i = 0; i < carosuelPost.length; i += 3) {
if(i == 0) activeClass = 'slideVisible';
jQuery(".post-slider-mango .fusion-posts-container").after('<a class="carousel-buttons"><li></li></a>');
jQuery(".carousel-buttons:eq(0)").on("click", function() {
jQuery(".slideElements").removeClass("slideVisible");
jQuery(".slideElements:eq(0)").addClass("slideVisible");
});
jQuery(".carousel-buttons:eq(1)").on("click", function() {
jQuery(".slideElements").removeClass("slideVisible");
jQuery(".slideElements:eq(1)").addClass("slideVisible");
});
}
});
So it's hard to say because it depends on the element that has the activeClass class and the heirarchy. You can have the .carousel-button on click remove the class from its parent, or parent's parent.
You can use .closest() to find the closest ancestor with x class. So:
// Declare function that removes a given class from given element
// Set click event listener for .carousel-button elements
$('.carousel-button').click(function(e){
e.preventDefault();
$(this).closest('div.slideVisible').removeClass('slideVisible');
});
Also to note, I would use a <button> element for the carousel-button so you do not then need to use the e.preventDefault() in the click event. If it is only to be used to run JavaScript via user interaction then you do not need to use an <a> tag.
See snippet for working example.
// Set click event listener for .carousel-button elements
$('.carousel-button').click(function(){
const next = $(this).closest('div.slideVisible').next().is('.slide');
if (next) {
return $(this).closest('div.slideVisible').removeClass('slideVisible').next().addClass('slideVisible');
} else {
return $(this).closest('div.slideVisible').removeClass('slideVisible').prev().addClass('slideVisible');
}
});
.slide {
display:none;
padding:2rem;
text-align:center;
background:orange;
}
.slide2 {
background:yellow;
}
.slideVisible {
display:block;
}
.carousel-button {
padding:1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="slide slide1 slideVisible">
<div class="buttons">
<button class="carousel-button">Hide Me!</button>
</div>
</div>
<div class="slide slide2">
<div class="buttons">
<p>This is slide 2</p>
<button class="carousel-button">Hide Me!</button>
</div>
</div>
Edit: This answer assumes that you're trying to remove the class from a parent of the button you're clicking. If you need to get it from the sibling before or after you can use .prev() and .next() after calling the .closest() method:
$(this).closest('div.slideVisible').prev().removeClass('slideVisible');
My function:
function ChangeStep(id)
{
var i = 1;
// hide all other tabs:
while(i<10) {
var divID = 'tabs' + i;
if (divID !== null) {
document.getElementById(divID).className += " hide";
}
i++;
}
// show this one
document.getElementById(id).className += " show";
}
How I'm calling it:
<div id="prev"><img src="img/prv.png" onClick="ChangeStep('tabs1'); return false;"></div>
<div id="next"><img src="img/nxt.png" onClick="ChangeStep('tabs2'); return false;"></div>
The Divs I want to show/hide:
<div id="tabs1" class="hide"><h1>Step 1</h1></div>
<div id="tabs2" class="show"><h1>Step 2</h1></div>
My Css:
.hide { visibility: hidden; }
.show { visibility: visible; }
Basically what I want to do is: When I click Next or Previous, show the corresponding "Tab" by hiding all the others and showing this. This should be done by adding the class "Hide" or "Show" depending on if it is to be hidden or visible.
You are always appending class names, so they will (after being shown once) be members of both the show and hide classes and both rulesets will apply (in the normal cascade order).
If you don't need to maintain any other classes, you can replace your append operator += with a simple assignment: =
If you do need to maintain other classes on the elements, then you can use classList instead.
document.getElementById(divID).classList.remove('show');
document.getElementById(divID).classList.add('hide');
If you need to support Old-IE then you can use a polyfill (which will probably run regex over the classList) or an API that provides similar functions. Most common JS libraries (such as YUI and jQuery) have one built in.
I'm trying to figure out the following.
I have following jQuery code:
var as = "";
var bPlay = 0;
audiojs.events.ready(function() {
as = audiojs.createAll();
$(".audiojs .play-pause").click(function() {
var e = $(this).parents(".audiojs").index(".audiojs");
$.each(as, function(t, n) {
if (t != e && as[t].playing) {
as[t].pause()
}
})
bPlay = !bPlay;
if (bPlay == 1) {
$(".bar").each(function(i) {
fluctuate($(this));
});
} else {
$(".bar").stop();
}
})
});
In a nutshell it preforms list of things when someone clicks particular .audiojs instance on a page. 1) checks if there is any other instance playing, if there is pauses it. And if it is playing applies fluctuate function to elements on a page that have class="bar". This is the issue! I don't want to apply it to all .bar's on a page, but only to a specific group that is associated with particular .audiojs instance (the one that is being clicked and is playing).
I thought of the following solution. Each .audiojs instance is inside a div tag that has id like "post-1", "post-2" etc.. where numerical value is post id from database. I can add this numerical id to bar, so it would be like bar-1, bar-2 etc... However after this I'm having issues.
For javascript to work I need to retrieve numerical value from "post-[id]" associated with audiojs instance that is being clicked and than store it somehow, so I can use it like this afterwards
bPlay = !bPlay;
if (bPlay == 1) {
$(".bar-[value retrieved from post-...]").each(function(i) {
fluctuate($(this));
});
} else {
$(".bar-[value retrieved from post...]").stop();
}
Could someone explain to me how it can be achieved?
Honestly, the easiest way would be to stick it in a custom data-* attribute on the <div id="post-X"> element, like so:
<div id="post-1" data-bar="bar-1">...</div>
Then, you said your .audiojs element is inside that <div>, so just go from this inside the event handler to that <div> element (using .closest()) and get the value of it:
var barId = $(this).closest('[id^="post-"]').attr('data-bar');
Then when you need to use it:
$("." + barId).each(function(i) {
fluctuate($(this));
});
Instead of embedding the value in a class or ID, use a data-* attribute:
<div class="audiojs" data-fluctuate-target="bar-1">
<button type="button" class="play-pause">
<!-- ... -->
</button>
</div>
<div class="bar-1">
<!-- ... -->
</div>
In your click event handler, use the following to fluctuate or stop the correct elements:
var fluctuateClass = $(this).closest('.audiojs').attr('data-fluctuate-target');
$('.' + fluctuateClass).each(function () {
if (bPlay == 1) {
fluctuate($(this));
} else {
$(this).stop();
}
});
I'm currently using this to get the class for a specific bit of HTML on the page:
$(this).parent("div").attr('class')
But that div has multiple classes: current_status status_billed
My end goal here is to grab the class that starts with status_ and replace it with a different class name.
So using my .parent() function above, I'm able to select the div I need, but I then need to remove the status_billed class and replace it with, for example, status_completed (or a number of other class names).
Select divs that have the status_billed class:
$(this).parent('div.status_billed')
Select divs whose class attribute contains status_:
$(this).parent('div[class*=status_]')
That's about the best you'll get with jQuery selectors. You can do better using .filter():
$(this).parent('div').filter(function ()
{
var classes = $(this).attr('class').split(' ');
for (var i=0; i<classes.length; i++)
{
if (classes[i].slice(0,7) === 'status_')
{
return true;
}
}
return false;
});
...but I'm not sure why you're doing all this - .parent() returns at most 1 element. Did you mean .closest() or .parents()?