RemoveClass and AddClass not working - javascript

I think this may be because these elements didn't originally have the DOM element. I have tried using events and then a propagation tool, but it's still not working :(
I want it so that when you click one of the items, it removes the underline from all items, and then adds it to the item that you just clicked, but in this case it keeps it underlined. To test just use the fiddle link and click on the first "A", and then the second bigger "A"
(JSFiddle)
$(document).ready(function() {
$("li.big").on("click", function(e) {
$("li>a.underline").removeClass("underline");
$("li.big").addClass("underline");
e.stopPropagation();
});
$("li.default").on("click", function(e) {
$("li>a.underline").removeClass("underline");
$("li.default").addClass("underline");
e.stopPropagation();
});
});
a {
text-decoration: none;
}
.underline {
text-decoration: underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav navbar-nav">
<li>
<div class="raisetext">Raise Text:</div>
</li>
<li class="default">A
</li>
<li class="big">A
</li>
<li class="bigger">A
</li>
</ul>

To add to Sushils answer, it sounded like the anchors were appended. So, just in case the anchor tags were dynamically appended to the page:
$(document).ready(function() {
$("li").on("click","a", function() {
$("li > a").removeClass("underline");
$(this).addClass("underline");
});
});

you can simply use $('a').on('click', function(){ instead of the li.big and li.default since they're all links.
try this
$(document).ready(function() {
$('a').on('click', function(){
$('a').removeClass('underline');
$(this).addClass('underline');
});
});
here's a working JSFIDDLE
note: this will apply to all the links on the page. if you don't wan't it to apply to all the links, then you can use a class.

Related

removing class attribute from li on click

I have the following code in html. I just want to remove active class when we click on other li and add active class to li on which it is clicked.
<ul class="pagination" id="paginationUL">
<li class="active">1</li>
<li onclick="javascript:selectThis()">2</li>
I tried to remove the class first and it is not working. Please suggest.
function selectThis() {
$('ul[class="pagination"] li[class="active"]').removeClass("active"));
}
Edited the script and it is working.
Your selectors are incorrect. You need to use the ID (#) or class (.) selector:
$('#paginationUL li.active').removeClass("active");
However, you're better off not using intrusive event handlers, and rather doing something along the lines of the following:
$('#paginationUL > li').on('click', function() {
$(this).addClass('active').siblings('.active').removeClass('active');
});
The latter example will apply a class of active to the clicked element and remove it from any other elements in the <ul>.
You can use something like this
$("#paginationUL li").click(function() {
$(this).toggleClass("active");
$(this).siblings().removeClass("active");
});
If you're using jquery this should do it:
$('#paginationUL li').click(function(){
$('#paginationUL li').removeClass("active");
$(this).addClass('active');
});
Your selector is incorrect. Use #paginationUL[class="pagination"] li[class="active"] or ul.pagination li.active or #paginationUL li.active
You can write a line to bind to all li elements in that menu. The $(this) selector acts against the element clicked on, while using .siblings() acts on all other child li elements.
$('#paginationUL > li').click(function(){
$(this).addClass('active').siblings().removeClass('active')
})
.active { background: orange; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="pagination" id="paginationUL">
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>

ul li selector doesn't work

I have an issue using jquery. I have a content that have to become visible when I click on ul li in navigation.
But I'm missing something, when I click, nothing happens. I am not sure why this happens. Please take a look at the provided fiddle near the bottom
Here is the code:
$(document).ready(function(){
$("ul.topnav > li.one").click(function() {
$('.content').hide(500).fadeOut(400);
if ($(this).next().is(':hidden') == true) {
$(this).next().show(400).fadeIn(500);
}
});
$('.content').hide();
});
<ul class="topnav">
<li class="one">test</li>
<li>second</li>
</ul>
<div class="content">Some content here</div>
Here is a fiddle http://jsfiddle.net/2pBge/
Here you go
http://jsfiddle.net/Mc92M/1/
$(document).ready(function(){
$("li.one").on("click", function() {
$('.content').fadeOut(400);
if ($('.content').is(':hidden')) {
$('.content').fadeIn(500);
}
});
$('.content').hide();
});
When you used .next() it is targeting the second li, not content div so nothing shows or hides. I also removed the .hide and .show as you already have fade in/out
If you really want to use the .next() then you would have to do
$(document).ready(function(){
$(".topnav").on("click", function(e) {
if( $(e.target).parent().is('li.one') ) {
$(this).next().toggle();
}
});
$('.content').hide();
});
First of all, your event isn't firing. Just set up a click listener for ul.topnav and delegate the event:
$("ul.topnav").on("click", "li.one", function() { ... });
Then, delete the rest of that nonsense and just use .toggle():
$('.content').toggle();
Working DEMO
$(document).ready(function(){
$("ul.topnav").on("click", "li.one", function() {
console.log('clicked!');
$('.content').toggle();
});
$('.content').hide();
});

How can I give the current page's link a disabled look?

In my web site, I have three pages: Home, About, and Contact. I want the current page's link to give some visual indication that clicking the corresponding link would be senseless as the user is already on that page. Is this task better handled by CSS or jQuery, and in either case, what is the most elegant solution that will also automatically apply to any pages which may be added in the future?
Here's my HTML diesbezueglich:
<nav>
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
UPDATE
I wonder why this didn't work; I added to Site.css this:
nav ul li a.current {
color: blue;
}
And the relevant HTML is:
<nav>
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
Yet the links remain the same (as Led Zeppelin predicted).
UPDATE 2
I tried this to test out kind of an amalgam of the various ideas proposed here:
In Site.css:
.current {
color: blue;
}
In _SiteLayout.cshtml:
<ul id="menu">
<li id="home" name="home">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
In Default.cshtml:
<script type="text/javascript">
$(document).ready(function () {
$("#tabs").tabs();
$(".fancybox").fancybox();
$("home").addClass('current');
});
</script>
...but no go; the "Home" link is as homely as ever (no pun intended).
I also tried giving all of the links an id of "location" and adding this to Default.cshtml's "ready" function:
if ($(#location).attr('href').indexOf('home') != -1) $('home').addClass('currentPage');
else if ($(#location).attr('href').indexOf('about') != -1) $('about').addClass('currentPage');
else if ($(#location).attr('href').indexOf('contact') != -1) $('contact').addClass('currentPage');
(where "currentPage" is the css class that sets the color to blue, and each nav link has an id of "location"); I reckon I would also have to add a "removeClass" for the two links with an index of -1 in each if/else block.
My beer is getting saltier by the nanosecond.
UPDATE 3
I tried this:
Added the IDs to the elements in _SiteLayout.cshtml:
<nav>
<ul id="menu">
<li id="home">Home</li>
<li id="about">About</li>
<li id="contact">Contact</li>
</ul>
</nav>
And added this to Site.css:
#home {color: orange;}
#home.current {color: blue;}
#about {color: orange;}
#about.current {color: blue;}
#contact {color: orange;}
#contact.current {color: blue;}
...but it did nothing - all the links are still gray no matter where I navigate.
UPDATE 4
Also tried this to no avail:
if ($('#home').attr('href').indexOf('Home') != -1) $('#home').addClass('currentPage');
UPDATE 5
I wonder if there's a way to use the _PageStart.cshtml to handle this? IOW, could I do something like:
#{
Layout = "~/_Layout.cshtml";
//pseudocode follows
var currentPage = CurrentPage.Id;
}
//and then some jQuery (also pseudocode):
if #currentPage == Default {
#home.display = none;
else if #currentPage == About {
#about.display = none;
else if #currentPage == Contact {
#contact.display = none;
} // perhaps set them all visible from the git-go
UPDATE 6
Another possibility that "jQuery for ASP.NET Developers" has inspired is something like the following inside the "ready" function (pseudocode; if this would work, I welcome the specific jQuery I would need to flesh this out):
// first set all of the nav ul li to their default color, right? (not shown)
// now, color the current one chartreuse:
$("nav ul li").each(function() {
switch ($(this.name)) {
case 'home':
$(#home).css("color", "chartreuse");
break;
case 'about':
$(#about).css("color", "chartreuse");
break;
case 'contact':
$(#contact).css("color", "chartreuse");
break;
}
});
UPDATE 7
Well, I'm sure this is nobody's idea of elegant, but I did figure out a way to accomplish it by using a click event for each li. Elegantizations welcome to the jsfiddle here: http://jsfiddle.net/vV4h5/1/
As to the elegantization of the jsfiddle above, there must be a way to do something like this instead:
jQuery(function () {
$("nav ul li").css("color", "black");
var currentLI = theOneClicked; //??? how to get this???
$(currentLI).css("color", "blue");
});
UPDATE 8
It works in jsfiddle, but not in my project; Having this in _SiteLayout.cshtml:
<nav>
<ul id="menu">
<li id="home">Home</li>
<li id="about">About</li>
<li id="contact">Contact</li>
</ul>
</nav>
. . .
jQuery(function () {
$("#home").click(function (event) {
$("#home").css("color", "blue");
$("#about").css("color", "black");
$("#contact").css("color", "black");
});
});
jQuery(function () {
$("#about").click(function (event) {
$("#home").css("color", "black");
$("#about").css("color", "blue");
$("#contact").css("color", "black");
});
});
jQuery(function () {
$("#contact").click(function (event) {
$("#home").css("color", "black");
$("#about").css("color", "black");
$("#contact").css("color", "blue");
});
});
...does not work. Neither does moving just the first function to Default.cshtml, so that it looks like this:
$(document).ready(function () {
$("#tabs").tabs();
$(".fancybox").fancybox();
$("#home").click(function (event) {
$("#home").css("color", "blue");
$("#about").css("color", "black");
$("#contact").css("color", "black");
});
});
I think this is pretty close to what you are looking for here:
http://jsfiddle.net/qmHeF/1/
JS:
$("#menu a").each(
function(index)
{
if(window.location.href==this.href)
{
$(this).parent().remove();
}
}
);
I remove it from the DOM here (my personal preference) but you can just add a class or custom CSS if you like.
http://jsfiddle.net/qmHeF/2/
Updated: Changed it to add a class instead of remove it.
$("#menu a").each(
function(index)
{
if(window.location.href==this.href)
{
$(this).addClass("current");
}
}
);
using window.location.href instead of the jquery href will give you the full URL instead of the relative url. That way you don't need to parse either url and you can just compare the two.
You have to create a CSS class for this active state, like suggested in the comment, I use current in this example.
.current {
text-decoration: none;
/* here you style the seemingly disabled link as you please */
}
As for the HTML, the active menu page would look like this:
If you are in the About page
<nav>
<ul id="menu">
<li>Home</li>
<li><a class="current" href="~/About">About</a></li>
<li>Contact</li>
</ul>
</nav>
If you want the link to be disabled, using only html, here goes the code. Fiddle was updated to show this code. An elegant solution using Javascript was provided below in the comments.
<nav>
<ul id="menu">
<li>Home</li>
<li><span class="current" >About</span></li>
<li>Contact</li>
</ul>
</nav>
I made a quick example here so you can see if this is what you're looking for:
Example in jsFiddle.net
Best wishes
UPDATED
On second thought, your problem is that when you click the link to a new page, you are refreshing the javascript...so the click event fires but then is immediately replaced by the original DOM elements for whatever page you browse to.
Use this instead:
HTML/Razor
<nav>
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
jQuery
$(document).ready(function () {
$("#menu a").each(function(){
//set all menu items to 'black
$(this).css("color","black");
var linkPath=$(this).attr("href");
var relativePath=window.location.pathname.replace('http://'+window.location.hostname,'');
//set the <a> with the same path as the current address to blue
if(linkPath==relativePath)
$(this).css("color","blue");
});
});
You can either check with some server-side language (e.g. PHP) to see if the current page is Home, About, or Contact, and apply a "current" class accordingly. Or, if you'd prefer, you can do this with JavaScript. I'm not sure how your absolute URLs look, but I would do something like this:
$(document).ready(function() {
$('a[href="' + window.location.pathname + '"]').addClass('current');
});
You may have to add some forward slashes in there, depending upon how your URLs look.
There are three sets of solutions to this universal development task: 1) server-side scripting alters menu/links for you, 2) CSS styling using something like a "current" class, or 3) javascript/css hybrid solutions.
It really all depends on your system and scope of development. For large dynamic sites, obviously one might as well use server-side code if it's already being used anyway. But for most projects where one isn't already using such scripting, one can manually add in a 'current' class to links and style them as you please with CSS or even more the anchor wrapping the text entirely (depending on your style of link/menus).
For a more robust javascript solution, you might try this: automatic link hightler/styling
function extractPageName(hrefString)
{
var arr = hrefString.split('/');
return (arr.length < 2) ? hrefString : arr[arr.length-2].toLowerCase() + arr[arr.length-1].toLowerCase();
}
function setActiveMenu(arr, crtPage)
{
for (var i=0; i < arr.length; i++)
{
if(extractPageName(arr[i].href) == crtPage)
{
if (arr[i].parentNode.tagName != "DIV")
{
arr[i].className = "current";
arr[i].parentNode.className = "current";
}
}
}
}
function setPage()
{
hrefString = document.location.href ? document.location.href : document.location;
if (document.getElementById("nav") !=null )
setActiveMenu(document.getElementById("nav").getElementsByTagName("a"), extractPageName(hrefString));
}
Then run setPage onload, such as with:
window.onload=function()
{
setPage();
}
As far as usability goes, it's generally accepted that just styling a nav link to look less interesting, lower contrast, grayer, not underlined, etc, is sufficient to help people know here they are. The cost of clicking a link where you already are is pretty low, but it's a nice design touch for most sites anyway.
to programmatically change my links, based on current url, i would prefer jquery:
<style type="text/css">
.current {
color: #cccccc;
}
</style>
...
<nav>
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
...
<script type="text/javascript">
$(document).ready(function() {
var href = $("#menu li a").prop("href");
$("a[href$='"+href.substr( href.lastIndexOf("/") )+"']").addClass("current");
});
</script>
..the jquery code adds the "current" class to any a link that has its href property set to last part of address (after last /). Thats not perfect anyway if your links are somewhat like /Contact/More..
Your "Update 2" version is close to working - you just need to add the class to #home, not home
Something like:
.current {
color: blue;
}
.current a {
text-decoration: none;
}
with:
// ...
$("#home").addClass('current');
// ...
How about something like this?
What we are doing here is that we call updateMenu with a string contained in the href attribute of a menu anchor. If the string and the anchor.href match, then we hide the anchor and copy it's text content to a new text node which we then append to the li element.
If we don't have a match then we unhide the menu anchor and check to see if the li element's (the parentNode in this case) last child is a text node, if it is we remove it because it was added by us.
You requested:
I want the current page's link to give some visual indication that
clicking the corresponding link would be senseless as the user is
already on that page.
This solution does that and also renders the link unclickable.
Of course it doesn't have to be exactly this formulation, but can be some other variant, and of course you can achieve this using jquery rather than vanilla javascript if you prefer.
HTML
<nav>
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
Javascript
(function () {
var updateMenu = (function () {
var anchors = document.getElementById("menu").getElementsByTagName("a");
return function (page) {
Array.prototype.forEach.call(anchors, function (anchor) {
var last;
if (anchor.pathname === page) {
anchor.style.display = "none";
anchor.parentNode.appendChild(document.createTextNode(anchor.textContent));
} else {
last = anchor.parentNode.lastChild;
anchor.style.display = "block";
if (last.nodeType === 3) {
anchor.parentNode.removeChild(last);
}
}
});
}
}());
setTimeout(function () {
updateMenu("/");
setTimeout(function () {
updateMenu("/About");
setTimeout(function () {
updateMenu("/Contact");
setTimeout(function () {
updateMenu("");
}, 5000);
}, 5000);
}, 5000);
}, 5000);
}());
On jsfiddle
I you want to use hrefs like in your example i.e. "~/About", then you will need to formulate your string to be passed to updateMenu, like so for my example;
HTML
About
Javascript
console.log(document.getElementsByTagName("a")[0].pathname);
console.log(window.location.pathname + "~/About");
Outputs
/Xotic750/G5YuV/show/~/About
/Xotic750/G5YuV/show/~/About
On jsfiddle
See window.location for it's other properties
Returns a location object with information about the current location
of the document.
For a purely css solution to this you could try pointer-events, here is a jsfiddle showing it in use.
Warning: The use of pointer-events in CSS for non-SVG elements is
experimental. The feature used to be part of the CSS3 UI draft
specification but, due to many open issues, has been postponed to
CSS4.
CSS
.current {
pointer-events: none;
cursor: default;
text-decoration: none;
color: black;
}
HTML
<nav>
<ul id="menu">
<li>Home</li>
<li><a class="current" href="/About">About</a></li>
<li>Contact</li>
</ul>
</nav>
Your update #2 should work, but you forgot to put "#" ($('#home').addClass...).
But if again it's not working, pay a particular attention to your CSS
If you have, for example, a css like
#home{color : blue;}
.current{color : orange;}
The text will be blue since #home is "stronger"
If we put values to selector:
id=10
class=5
node selector (div) = 1
so #home = 10 and is higher than .current wich equal 5, #homestyles will override.
you could use li.current but again, 5+1=6 wich is lower than an id.
But #home.current will equal 15! Wich will overide #home styles!
But if your color style is on the node itself with the attribute style="" you have to remove it with jquery or use !important :
.current{
color: blue !important;
}
It will override EVERY css but it is not recommended.
Your update #3 was close.
give your body an ID whatever name you want the page to be and give your links ids like so
<body id="about">
<nav>
<ul id="menu">
<li class="home">Home</li>
<li class="about">About</li>
<li class="contact">Contact</li>
</ul>
</nav>
</body
Then your CSS can look somewhat like your update #3 example:
li a {color:blue}
#home .home{color:red !important}
#about .about{color:red !important}
#contact .contact{color:red !important}
This should ignore any classes that are not being used and only color the selected one red.
I hate to point out that the reason your css color is not being applied to your link is because css colors for links must be set on the anchor tag (an anchor tag will not inherit a color from a wrapping LI element). Try
.current a {color:#123456;}
or leave your css as is, but change your markup so the "current" class is applied to the < a > tag instead of the < li >.
EDIT: The reason your jsfiddle works when attempting to change colors (while your production code doesn't) is because the fiddle text is not inside of an A tag.
If you wish to automatically detect which page you are currently on, simply compare the HREF value of each link to the document.URL string:
$('nav').find('a').each(function(){
if ( document.URL.indexOf( $(this).attr('href') ) !== -1 ){
$(this).parent().addClass('current');
}
});
Detailed description & test available here: -> http://jsfiddle.net/vV4h5/26/
EDIT #2: One more thing... your asp.net links are going to mess with this a bit as the document.URL will not contain the ~ character... simply remove the first character from your href value as follows:
var href = $(this).attr('href').split(1); //
if ( document.URL.indexOf( href[1] ) !== -1 ){
...
I'd just remove the linkyness from the one you are currently on. You can control the styling by targeting li and li a differently in your CSS. The only slightly tricky thing is to get the actual href value right for the links you are using, but that shouldn't be too hard. And it's not a lot of code.
$(function(){
var href = window.location.pathname.replace(/.*\//, "/"),
$active = $("nav ul#menu a[href='"+href+"']");
$active.replaceWith($active.text());
});
I use these on my website. It doesn't use JavaScript but it does pretty much what you are asking.
<style>
.header-nav a:target {
pointer-events: none;
color: #000;
font-weight: bold;
text-decoration: underline;
}
</style>
<p class="header-nav">
<a id="headerabout" href="/about.html#headerabout">about</a>
|
<a id="headertags" href="/tags.html#headertags">tags</a>
|
<a id="headershit" href="/shit.html#headershit">Shit I say</a>
</p>
It adds id to anchor and its target URL. If the anchor is :target-ed, they will be disabled completely. Also, adding an # to href attribute will cause an anchor to not refreshing when clicked if the current page match the anchor target page.

Add/Remove classes and using Cookie to remember selection

I have this simply piece of JQuery that toggle a class on anchor tags/links.
What I don't know is how do I make the class toggle or add/remove when the other links are clicked? Example: The class can only apply to the link that is click and cannot be on more than one at a time. That's where I am stuck. Well, I don't know how to do it.
Secondly how do I use the JQuery Cookie to keep the currently link active. I have downloaded the cookie extension.
Here is what I have done:
HTML:
<ul class="navbar">
<li>Link1</li>
<li>Link2</li>
<li>Link3</li>
</ul>
CSS:
.activeLink{
color: #930;
}
JQuery:
$(document).ready(function() {
$('.navbar li a').click(function(){
$(this).toggleClass('activeLink');
});
});
Thank you!!
Below is a solution that uses event propagation:
$(function() {
var $activeLink,
activeLinkHref = $.cookie('activeLinkHref'),
activeClass = 'activeLink';
$('.navbar').on('click', 'a', function() {
$activeLink && $activeLink.removeClass(activeClass);
$activeLink = $(this).addClass(activeClass);
$.cookie('activeLinkHref', $activeLink.attr('href'));
});
// If a cookie is found, activate the related link.
if (activeLinkHref)
$('.navbar a[href="' + activeLinkHref + '"]').click();
});​
Here's a demo (without the cookie functionality as JSFiddle lacks support).
Here is how I do it. It's a little simplistic, but it gets the job done without a lot of brain strain.
<ul class="navbar">
<li>Link1</li>
<li>Link2</li>
<li>Link3</li>
</ul>
<script>
$(document).ready(function() {
$('.navbar li a').click(function(){
$('.navbar li a').css('color', 'black');
$(this).css('color', '#930');
});
});
</script>

jQuery .hover() is driving me crazy

I have a project that uses drop-down menus that are nested ul's, like so:
<ul id="nav">
<li id="thome" class="navtab">
HOME
<ul id="subnav_home" class="submenu">
<li>Dashboard</li>
<li>SMS</li>
<li>Email</li>
<li>Twitter</li>
</ul>
</li>
</ul>
Using jQuery, I've added a .hover() to the .navtab li that .show()s the .submenu ul. The problem is that when the cursor moves into the new ul, the .hover()-out for the .navtab fires, .hide()ing the sub-menu, despite the fact that I have the height of the li so that it entirely wraps the .submenu ul.
I've tried adding a delay to the .hide(), but if you pass your cursor over the navtab bar quickly, you get all of the sub-menus at once.
Any solutions for me? Here's the relevant JavaScript. The hide() function is identical to .show() except that it shrinks the height and hides the ul (obviously).
$('.navtab').hover(
function(){
tabShowSubnav($(this).attr('id'));
},
function(){
tabHideSubnav($(this).attr('id'));
});
function tabShowSubnav(menu){
var sb = '#' + menu + ' > .submenu';
var tb = '#' + menu;
$('.navtab').each(function(){
if (!$(this).hasClass('current_page')){
$(tb).addClass('nav_hover');
}
});
$(tb).css('height','239px');
$(sb).show();
}
$('.navtab').hover(
function() {
$(this).children(".submenu").show().children('current_page').addClass("nav_hover");
},
function() {
});
$(".submenu").mouseout(function(){
$(this).hide();
});
$('.navtab').hover(
function() {
$(this).children(".submenu").show().children('.current_page').addClass("nav_hover");
},
function() {
$(this).children(".submenu").hide();
});
This worked for me.
I finally had to go with the jQuery plugin hoverIntent, that ignores children for the purpose of mouseout.

Categories