how to addClass and removeClass in an anchor - javascript

What I want is when I click an anchor it will add a class.
My markup:
<ul>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
</ul>
Say If I clicked the class="promo-call" it will add class active-call and when I clicked promo-text, it will add class active-text.
Just to be clear on what's on my mind:
E.g:
When clicked promo-call
When clicked promo-text
When clicked promo-data
And so on...
Also when an anchor is active the rest must be inactive, will return to their original class.
I have this code right now:
Just a trial and error. For now I'm just playing the two anchor: class: promo-call & promo-text. What's odd is I have to click twice the button for the background image to show.
jQuery(document).delegate(".promo-call","click",function(e){
jQuery(".promo-text").removeClass("active-text");
jQuery(".promo-call").addClass("active-call");
});
jQuery(document).delegate(".promo-text","click",function(e){
jQuery(".promo-text").addClass("active-text");
jQuery(".promo-call").removeClass("active-call");
});
FYI: I'm using Jquery-Mobile.

try this:
var promobtt = $('a[class^="promo"]');
promobtt.on('click', function(evt) {
evt.preventDefault();
promobtt.removeClass('active-text active-data active-call ...');
$(this).addClass(this.className.replace(/^promo/, "active"));
});
Note that here promobtt.removeClass('active-text active-data active-call ...'); you have to list all active classes you need to use.
Otherwise you should provide one unique "active" class (e.g. active) instead of <n> different active classes: if you're doing this only for a matter of styling you could style you links anyway with one class doing like so.
.promo-text { ... }
.promo-text.active { ... }
.promo-data { ... }
.promo-data.active { ... }
and so on. This would simplify both css code and javascript code because following this way you would only need a toggleClass('.active') applied to all links.

$('a[class^="promo"]').on('click', function() {
$.each('a[class^="promo"]', function() {
$(this).attr('class','');
});
var currentClass = $(this).attr('class');
if(currentClass)
{
var startClass = string.split('-');
if(startClass.length > 1)
{
$(this).toggleClass('active-' + startClass[1]);
}
}
});
Note that this will only work for single-classed elements as in your example.

With .toggleClass("promo-call") you can get this result

Related

document.querySelector() always selects the element with the class "Open" even after it has been removed and replaced with the class "Close" | Vue3 js

So I was trying to find a Vue Solution of the jQuery SlideUp() and slideDown() functionality. And I have run into a problem while creating the same for my Side Bar Menu Open and Close funtion. See my code below:
UPDATE: Here's the stackblitz link to the problem: https://stackblitz.com/edit/vue-lvjxmz
I'd really appreciate if someone helps me to solve this problem. Thanks.
export default {
mounted() {
let hasSubmenu = Array.from(document.querySelectorAll(".hasSubmenu.close"));//Select all hasSubmenu
let self = this;
hasSubmenu.forEach(function (el) {//Show Hide Submenu Based On Clicks
el.addEventListener("click", self.menuOpen.bind(this, el));
});
},
methods:{
//Menu Opener Function
menuOpen(el){
let ul = el.querySelector("ul");
ul.style.height = `${ul.scrollHeight}px`;
el.classList.remove("close");//Remove The Class "close"
el.classList.add("open");// add the class "open"
this.menuClose();//Call this function to close the menu
},
//Menu Closer Function
menuClose(){
console.log(document.querySelector(".hasSubmenu.open"));//Log the Selected Element
document.querySelector(".hasSubmenu.open").addEventListener("click", function (e) {
e.currentTarget.querySelector("ul").style.height = "0px";
e.currentTarget.classList.remove("open");
e.currentTarget.classList.add("close");
});
}
},
}
<ul id="main-nav">
<li class="hasSubmenu close">
<div> Main Menu One</div>
<ul style="height: 0px">
<li>
Sub Menu One
</li>
<li>
Sub Menu Three
</li>
</ul>
</li>
</ul>
So what we are doing here is: we are first selecting all the hasSubmenu items with the class close has in it. Then firing the click event where the menu opens and replace the class close with "open". Then we are calling the menuClose function where we are selecting the element which has the .open class. then firing another click event when the menu closes and removes the class .open and adds .close again.
The problem is somehow the menuClose function keeps selecting the element as if it was pointing to the hasSubmenu element and caching it in, it doesn't matter whether the class has been changed or not. I mean, even after the .open class has been removed on the click event it stills selecting it and thus clicking on the menuItem after the first 2 clicks the menuOpen function first opens the menu then calls the menuClose function and immediately closes the menu again although menuClose functionality only added to document.querySelector(".hasSubmenu.open"). As if, it first selected the element itself not the class and cached it in.
Okay, as per James Reply I have managed to solve the problem in another way. So the solution goes as below:
// Simply write one function and check if the submenu's
// height is 0px or not. Based on that write your
// open and close logics
menuOpenClose(el){
let ul = el.querySelector("ul");
let getHeight = ul.style.height;
console.dir(getHeight);
if (getHeight == '0px' || !getHeight.length) {
ul.style.height = `${ul.scrollHeight}px`;
el.classList.remove("close");
el.classList.add("open");
} else{
ul.style.height = `0px`;
el.classList.remove("open");
el.classList.add("close");
}
}

How to find the class of element in a each loop

I am trying to create a menu system where I can change the style of the active page item in the menu. I am using a separate body class on each page, then I want to cycle through the li in the menu and find a match to the body class. At that match I will add the new styling to that menu item.
Here is my code so far.
HTML
<body class="home-state">
...
<div class="menu-left">
<ul>
<li class="home-state">
Home
</li>
<li class="work-state">
Work
</li>
<li class="services-state">
Services
</li>
<li class="about-state">
About
</li>
<li class="blog-state">
Blog
</li>
<li class="shop-state">
Shop
</li>
<li class="contact-state">
<a data-toggle="modal" href="#modal-coworking">Contact</a>
</li>
<li class="project-state">
Project brief
</li>
</ul>
</div>
...
</body>
JS
var bodyClass = $("body").attr('class');
$('.menu-left ul li').each(function(){
First: I want to find the element's class here I have used $(this).attr("class"); which didn't work
var element = $(this);
Second: I want to use a if statement to check to see if the class matches the bodyClass
console.log(element);
Last: If there is a match I want to add the class .active to the element li.
});
Given that elements can have multiple classes, I'd suggesting changing your body element to use a data- attribute rather than a class to specify what the current page is:
<body data-current="home-state">
Then the JS needed to add the active class to the relevant menu item is simple:
$("li." + $("body").attr("data-current")).addClass("active")
You don't need to loop over the menu items comparing classes as mentioned in the question, because you can just directly select the required li element based on its class.
In the event that the body element doesn't have a data-current attribute then $("body").attr("data-current") would return undefined, which would mean the code above tries to select an element with $("li.undefined") and add a class to it. Probably you have no elements with such a class so that would be harmless, but if you wanted to explicitly test that the data-current attribute exists:
var current = $("body").attr("data-current")
if (current) {
$("li." + current).addClass("active")
}
You can do this in couple ways, here is the simple way to do this;
var bodyClass = $("body").attr('class');
$("li." + bodyClass).addClass("active")
You can also use a loop for this one;
var bodyClass = $("body").attr('class');
$(".menu-left li").each(function(i, classes) {
if (bodyClass === $(this).attr("class")) {
$(this).addClass("active")
}
})
both will do the job.
enter image description here
enter image description here
as the comment said,the element can have more than one class ,so you should check it one by one
You missed to bind the click event for the menu item. Follow like below
var bodyClass = $("body").attr('class');
$('.menu-left ul li').on( "click", function() {
var myClass = $(this).attr("class");
alert(myClass);
});
Tested: https://codepen.io/anon/pen/XzYjGY

jQuery Clickable Dropdown with CSS Animation issue

Please check out this fiddle: https://jsfiddle.net/willbeeler/tfm8ohmw/
HTML:
Do it! Roll me down and up again!
<ul class="roll-btns">
<li>Milk</li>
<li>Eggs and Cheese</li>
<li>Bacon and Eggs</li>
<li>Bread</li>
</ul>
jQUERY
$('.roll-btn').click(function() {
var ctrls = '.control';
if ($(ctrls).hasClass('noshow'))
{
$(ctrls).each(function() {
$(this).removeClass('noshow');
$(this).addClass('fadeInDown');
});
} else {
$(ctrls).each(function() {
$(this).removeClass('fadeInDown');
$(this).addClass('fadeOutDown');
});
}
});
This is a pretty simple thing, but I'm having trouble implementing it. Basically, the class "noshow" is a toggle for the A elements. If it does not exist, then add the CSS animation to the A element. If the CSS animation exists, add another css element to hide the A elements. I've tried delaying the "noshow" class, and other methods to no avail. This entire example works correctly with the first two clicks, but because it doesn't add the noshow class, it won't work after that. Basically, I need to add the noshow class on the second click AFTER the CSS animation gets done playing.
$('.roll-btn').click(function() {
var ctrls = '.control';
if ($(ctrls).hasClass('noshow') || $(ctrls).hasClass('fadeOutDown')) {
$(ctrls).each(function() {
$(this).removeClass('noshow');
$(this).addClass('fadeInDown');
$(this).removeClass('fadeOutDown');
});
} else {
$(ctrls).each(function() {
$(this).removeClass('fadeInDown');
$(this).addClass('fadeOutDown');
});
}
});

Trying to do a:active to stay on untill other link is clicked

What I'm trying to do is this: I have two links hot/update. When hot is clicked it should turn red and update to be black. When update is clicked it should turn red and hot to be black.
This works on a Fiddle, but not on my website.
I was able to find various answers on SO, as this seems like a common thing to ask. I was implementing one by one, but none of them works. They seem to work fine in fiddle but not on my web.
HTML:
<div id="Space" >
<ul>
<li role="presentation" class="sort">
<a class="link" href="/?sort=score&page=1" style="text-decoration:none;">hot</a>
</li>
<li role="presentation" class="date">
<a class="link" href="/?sort=date&page=1" style="text-decoration:none;">update</a>
</li>
</ul>
</div>
JavaScript:
$(function() {
var links = $('a.link').click(function() {
links.removeClass('active');
$(this).addClass('active');
});
});
CSS:
a.link.active { color: red; }
a, a:visited { color: black }
Right now, this does what a:active does, it won't stay red.
var links = does not do what you think it does.
You are thinking it is doing this:
var links = $('a.link');
But, since you're assigning it to the actual click event, it's not resulting in that selector.
You need to revise your code as follows:
// This is a "safer" document ready, to prevent conflicts with other $ libraries
jQuery(function($) {
$('a.link').click(function() {
// Remove the class from all other links
$('a.link').removeClass('active');
// Add the class to _just this link_
$(this).addClass('active');
});
});
Or, a version that preserves the var links:
// This is a "safer" document ready, to prevent conflicts with other $ libraries
jQuery(function($) {
// Assign all links to the "links" variable
var links = $('a.link');
links.click(function() {
// Remove the class from all other links
links.removeClass('active');
// Add the class to _just this link_
$(this).addClass('active');
});
});
Here's a working fiddle: https://jsfiddle.net/cale_b/tqzt8f7s/1/
So to clarify you want certain buttons to be highlighted based on whether or not the url has a certain query. Highlight sort if url contains /?sort=score&page=1 and highlight date if url contains /?sort=date&page=1.
To do this all you need to do is search for each of those strings inside of your page's (window.location.search). The code for such a thing would be.
const highLightWhat = (window.location.search).search('sort=score') !== -1 ? 'Highlight sort' :
(window.location.search).search('sort=date') !== -1 ? 'Highlight date' :
'Highlight Nothing';
This flag then can be used as a reference to highlight one 'a' tag or another.
I hope this helped! (:
Try this javaScript once
$(function() {
$('a.link').click(function(event) {
event.preventDefault();
$('a.link').removeClass('active');
$(this).addClass('active');
});
});

Changing the background color of a link after being clicked

I'd like to ask how to change the background color of each link (the rectangular shape surrounding it) to one different color after a link is clicked, and the other links still remain in its original background color.
Each link corresponds to one div placed in the same html file (that I didn't include here).
The point is to let the viewers know which link they are at. By the way, if it is okay I'm looking for the fastest code possible ^_^ (pure css, javascript or jQuery). Appreciate all suggestions!
the highlight only applied to the current link only! (the others will have the normal colors)
<div id="Navigation">
<div id="nav_link">
<ul id="MenuBar" class="MenuBarHorizontal">
<li><a class="MenuBarItemSubmenu" href="javascript:showonlyone('Index_frame');" >Home</a>
<ul>
<li><a href="javascript:showonlyone('Specification_frame');" >Specification</a></li>
<li><a href="javascript:showonlyone('Images_frame');" >Images</a></li>
<li>Video</li>
<li>Contact</li>
</ul>
</li>
<li><a href="javascript:showonlyone('Specification_frame');" >Specification</a></li>
<li><a href="javascript:showonlyone('Images_frame');" >Images</a></li>
<li>Video</li>
<li>Contact</li>
</ul>
</div>
<!--End of nav_link-->
</div>
<!-- End of Navigation-->
function showonlyone(thechosenone) {
$('.newboxes').each(function(index) {
if ($(this).attr("id") == thechosenone) {
$(this).show(1000).fadeIn(500);
}
else {
$(this).hide(1500).fadeOut(500);
}
});
}
EDITED
Guys, there is this one thing that I'm still stuck at even though I spent time on it a lot, I added some more JavaScript links the same with the above in the page with the idea that these new links will be functional just like the former. That is being clicked on ==> the highlight will appear only on these Navigation links. I tried to modify the function from jjurm like this
$(function(){
$("#MenuBar a,#colOne a").bind("click", function(){
var names=$(this).attr('name');
$("#MenuBar a").removeClass("clicked");
$("#MenuBar a[name='names']").addClass("clicked");
});
});
It didn't work and neither did the old ones that used to work
In a similar question to yours I once found out that only changes in text color are allowed some properties can be changed if you use a:visited pseudo-class (UPD: and background-color is one of them). But since your links are javascript links, the :visited selector will not work, hence you cannot do it as a pure CSS solution. You will have to use some kind of javascript. If jQuery is ok, you can try this:
$('a').on('click', function(){$(this).css("background-color","yellow");});
Perhaps you can change the "showonlyone" function? Then you could add the background changing code to it.
You can do this by simple css code:
#MenuBar a:visited {
background: yellow;
}
Edit:
As far as this doesn't work with javascript links (but I haven't tried it), there is other solution with jQuery and CSS.
jQuery code:
$(function(){
$("#MenuBar a").bind("click", function(){
$(this).addClass("clicked");
});
});
CSS:
#MenuBar a.clicked {
background: yellow;
}
Edit2:
Ok, if you want to keep highlighted only last clicked element, it's enough to add this simple line to javascript code:
$(function(){
$("#MenuBar a").bind("click", function(){
$("#MenuBar a").removeClass("clicked"); // Remove all highlights
$(this).addClass("clicked"); // Add the class only for actually clicked element
});
});
Edit3:
If you want to have more links that point to same location and to highlight all of them if one is clicked, follow this:
$(function(){
// Assume that your 'a' elements are in #MenuBar and #colOne
$("#MenuBar a, #colOne a").bind("click", function(){
// Remove all highlights
$("#MenuBar a, #colOne a").removeClass("clicked");
// Store the name attribute
var name = $(this).attr("name");
// Find all elements with given name and highlight them
$("#MenuBar a[name='"+name+"'], #colOne a[name='"+name+"']").addClass("clicked");
});
});
You can add an active class to the clicked anchor. Using live NodeList should work really fast as you also need to unselect previously selected item:
var a = document.getElementById('Navigation').getElementsByClassName('active');
$('#Navigation').on('click', 'a', function() {
if (a[0]) a[0].className = '';
this.className = 'active';
});
http://jsfiddle.net/vBUCJ/
Note: getElementsByClassName is IE9+ if you need to support older versions use jQuery:
var $a = $('#Navigation a');
$('#Navigation').on('click', 'a', function() {
$a.removeClass('active');
$(this).addClass('active');
});
http://jsfiddle.net/vBUCJ/1/
$('#MenuBar').on('click', 'a', function() {
$(this).css('background-color', '#bada55');
});
or if you need unique colors you can use the data-attribute.
$('#MenuBar').on('click', 'a', function() {
var $elem = $(this);
$elem.css('background-color', $elem.data('color'));
});
I'd recommended adding classes instead and using css to define styles.
$('#MenuBar').on('click', 'a', function() {
$(this).addClass('clicked-menu-link');
});
edit:
To remove the other clicks use:
$('#MenuBar').on('click', 'a', function() {
var fancyClass = 'clicked-menu-link';
$('#MenuBar a').removeClass(fancyClass).filter(this).addClass(fancyClass);
});

Categories

Resources