I'm pretty new to jquery and I decided to build a jquery tabber. So far so good but I have a little problem!!! I cant see how I can activate the tabber based on the URL. For instance when the link is www.myweb.com#tab2, the second tabber becomes activated. My jquery is as follows. Now I know jquery has it's own tabber script but I don't want to use it. So anybody else help me accomplish this please
Javascript
$(document).ready(function() {
var hash = location.hash;
var link1 = ("ul#tabs li a[href='" + hash + "']")
var link2 = ("ul.tabs li a[href='" + hash + "']")
var link3 = ("ul#tabs li[href='" + hash + "']")
$(".tab_content").hide(); //Hide all content
if ((link3.length)(link2.length)(link1.length))
{ //check if such link exists
$(link3, link2, link1).parent().addClass("active"); //Activate tab
$(hash).show();
}
else {
$("ul.tabs li a:first, ul#tabs li:first, ul#tabs li a:first").addClass('active');
$(".tab_content:first").show()
// On Click Event
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
return false;
});
});
HTML
<ul class="tabs">
<li>Design Team</li>
<li>Publications</li>
<li>Awards & Recognitions</li>
<li>Our Mission</li>
<li class="last-item">Company Profile</li>
</ul>
this is how far I have come. Since I have 3 selectors the jquery code is weirdly not working how do I achieve this so tabber is activated based on URL? Thanks
Look at JQueryUI, they have pre-built components like this.
Specifically: http://jqueryui.com/tabs/
Edit:
Or is their a specific reason why you are building your own?
You can set the selected tab using the following :
$(document).ready(function() {
$('#tabs').tabs(); // make jquery tabs
$("#tabs").tabs("select", window.location.hash);
});
Second parameter of $.tabs function accept either index or a selector.
Related
(All child is active as shown in the picture)
I want to add class="active" to parent when its child is clicked. I manage to add class "active" to parent but all the child is added class= "active" too. What i want is only the chosen child and its parent is "active".
Jquery:
$(document).ready(function(){
var pathname = window.location.pathname;
var filename=pathname.replace(/^.*[\\\/]/, '');
var currentLink=$('a[href="' + filename + '"]'); //Selects the proper a tag
currentLink.parents('.doctormenu').find('li a').removeClass('active');
currentLink.parentsUntil('.doctormenu', 'li').addClass('active');
//currentLink.parent().addClass("active");
//alert(filename);
})
Html:
<ul class="doctormenu">
<li>home</li>
<li>about</li>
<li>Disease</li>
<li>Search</li>
<li><a href="#" >
Services</a>
<ul>
<li>Self Diagnosis</li>
<li>Online Consultation</li>
<li>Clinic Appointment</li>
</ul>
</li>
</ul>
Here's a fiddle with a proper demo
The important code would be this:
// you can change this on.hashchange for the on.documentready
$(window).on('hashchange', function () {
// select a reference, in your case can be the pathname or whatever
var ref = location.hash
// find the matching element
var $el = $('a[href="' + ref + '"]')
// and it's closest parent (avoid select other
// parents and it's less risky than .parent)
var $menu = $el.closest('.doctormenu')
// remove previous active, if there's any
// (may you don't need this if the page is reloading)
$('.doctormenu')
.removeClass('active')
.find('a')
.removeClass('active')
// execute the needed operations, adding class in this example
$el.addClass('active')
$menu.addClass('active')
});
$('.doctormenu li a').each(function(){
// and test its normalized href against the url pathname regexp
if(urlRegExp.test(this.href.replace(/\/$/,''))){
$(this).parent().addClass('active');
}
});
I'm using .load to switch content in my #content div but when I click on a link it brings me to a white page saying "cannot get /index" or whatever.
The initial content does get loaded so I know the first three lines of code work.
Any ideas why I "cannot get" my other files?
Here's my HTML
<div id="nav">
<ul>
<li>Home</li>
<li>Portfolio</li>
<li>About</li>
</ul>
</div>
And the Jquery
$(document).ready(function() {
// initial
$('#content').load('content/index.html');
// handle menu clicks
$('ul#nav li a').click(function() {
var page = $(this).attr('href');
$('#content').load('content/' + page + '.html');
return false;
});
});
Here is the answer -
$(document).ready(function() {
// initial
$('#content').load('content/index.html');
// handle menu clicks
$('div#nav ul li a').click(function() {
var page = $(this).attr('href');
$('#content').load('content/' + page + '.html');
return false;
});
});
Shortly, the #nav is the id of the div not the ul so $('ul#nav li a'). should have been $('div#nav ul li a'). more precisely $('div#nav > ul > li > a').
If you want animations like fade, try this -
$('div#nav ul li a').click(function() {
var page = $(this).attr('href');
$('#content').fadeOut('fast', function(){
$('#content').load('content/' + page + '.html', function(){
$('#content').fadeIn('fast');
});
});
return false;
});
But for sliding animation its gonna be a little tricky, cause you have to do something like that -
Fist slide left by animating width
Then take the div to the right end of the window using css left
Load it and make the width normal
change the left to make it slide left again.
This will give you a space between animations, but if you want spaceless animation, then you will have to use more divs and a little more logics. Happy experimenting.. :)
When the content is loaded dynamically the actions on html elements will not be catched by direct .click() function So:
Use $(document).on('click', 'ul#nav li a', function() {
Instead of $('ul#nav li a').click(function() {
This Worked for me
As per your edit
You have a wrong jQuery selector, it should be -
$('#nav ul li a').click...
I have two separate ULs as menus. I'd like the second menu items to change text color when I hover the first menu items. Maybe a solution where the links with the same href as the link you hovered change css class? How could I do that with jQuery?
<ul class="firstMenu jQueryHover">
<li>bla</li>
<li>bla2</li>
</ul>
<ul class="secondMenu">
<li>blabla (same href as firstMenu item you hovered changes this elements css class)</li>
<li>blabla (same href as firstMenu item you hovered changes this elements css class)</li>
</ul>
If you want to affect all the links with the same href, including the one that was hovered over:
$("a").hover(function() {
$("a[href='" + $(this).attr("href") + "']").addClass("yourClass");
}, function() {
$("a[href='" + $(this).attr("href") + "']").removeClass("yourClass");
});
This makes use of the attribute name selector, to find all links with the same href as the currently hovered link.
Here's a working example.
If you wanted to make it so only the other links change (and not the hovered one) then you can make use of the jQuery not method to exclude the hovered element. It's not clear from your question whether you want all links with the same href to change, or all other links but not the currently hovered one.
$("a").hover(function() {
$("a[href='" + $(this).attr("href") + "']").not(this).addClass("yourClass");
}, function() {
$("a[href='" + $(this).attr("href") + "']").not(this).removeClass("yourClass");
});
To change all anchor tags with the same href
$("a").hover(function() {
$("a[href='" + $(this).attr("href") + "']").addClass("hover-class-name");
}, function() {
$("a[href='" + $(this).attr("href") + "']").removeClass("hover-class-name");
});
However, I can not see why you want to have two links with the same href on the page? Have you thought about using class names rather than the href to link the anchors?
Should be simple:
$(".jQueryHover a").hover(function(){
if($(this).hasClass("hovering"))
{
$(this).removeClass("hovering");
$('a[href="'+$(this).attr('href')+'"]').removeClass("hovering");
}
else {
$(this).addClass("hovering");
$('a[href="'+$(this).attr('href')+'"]').addClass("hovering");
}
});
Example
You could do:
$('.firstMenu ').hover(function(){
var href = $(this).attr('href');
$('.secondMenu a[href='+href+']').addClass('newClass');
},
function(){
var href = $(this).attr('href');
$('.secondMenu a[href='+href+']').removeClass('newClass');
}
);
I'm having trouble with a little jQuery, and thought someone in the community could help me out? So, my markup is as follows:
<div class="left">
<ul id="editing-nav">
<li><a class="active testforso" href="#TestForSO">Test For SO</a></li>
<li><a class="testforso2" href="#TestForSO2">Test For SO2</a></li>
...and so on.
</ul>
</div>
<div class="scroll">
<div class="scrollContainer">
<div id="testforso">
...some content
</div>
<div id="testforso2">
...some content
</div>
...and so on.
</div>
</div>
So, basically - .left is floated left, and .scroll is on the right side. I am looking for a way so the active nav element (by default, the first one, and then when the user would click another one, it'd assign that element a class of ".active" and remove the previous one's active class)'s co-insiding div has a display:block, while all others hide. I'm doing this inside of fancybox, which makes it a little bit more complicated, but here's what I have now -
$('#editing-nav li > a').click(function() {
$('#editing-nav li > a').removeClass('active');
$(this).addClass('active');
activeClassID = $(this).attr('class'); // grabs the nav class for the id to show in .scroll
var divIDToShow = ('.scroll .scrollContainer #') + activeClassID; // grabs the DOM path & ID of the coinciding div to show
divIDToShow = divIDToShow.replace(' active', ''); // removes " active" from the class (because before it would have a class of "testforso2 active"; now it just has "testforso".
$('.scrollContainer div:not(#' + divIDToShow + ')').hide();
$('.scrollContainer #' + divIDToShow ).show();
});
This works for the first link someone clicks, but not after that. I don't know if I was clear earlier, but the class for the #editing-nav li a co-incides with what div to show inside of .scroll.
Any ideas? I'm not sure why it's doing this... Thank you!
This issue is with your id selector - try this instead
EDIT
Figured out the real issue here - not sure why it works the first time but your divIDToShow variable contains too much information. See here for a cut down version
The reason why it's doing this is probably because it ran into an error during the first click. 'active testforso'.replace(' active') evaluates to 'active testforso' because there is no ' active' in the string. Even if you fix that, you don't know whether 'active' is in front or at the back of the class string. You could instead do .replace(/\s*active\s*/, '') , but my example below just removes all spaces.
I think you could probably change your code to something like:
$('#editing-nav li > a').click(function() {
$('#editing-nav li > a:active').removeClass('active');
$(this).addClass('active');
activeClassID = $(this).attr('class'); // grabs the nav class for the id to show in .scroll
var divIDToShow = activeClassID; // grabs the DOM path & ID of the coinciding div to show
divIDToShow = divIDToShow.replace('active', '').replace(/\s+/g,''); // removes "active" from the class then remove all spaces in what's left - "testforso2 active"; now it just has "testforso".
$('.scrollContainer div:not(#' + divIDToShow + ')').hide();
$('#' + divIDToShow ).show();
});
BUT:
Instead of doing all these, you might want to use the jQuery-BBQ plugin which allows you to track states through the hash. So you can just detect changes in the hash like, for example, using the hash as the id itself.
I needed some method of adding/removing classes of a parent element when it's children are clicked to reflect which child is currently selected. In this case a UL parent and LI children in a tab scheme. I needed a way to mark the current tab on the UL so I could style a background sprite on the UL; since styling my LI's backgrounds would not work with the graphics in this case.
I am a jQuery/Javascript/DOM novice, but was able to piece together an ugly solution for starters,
HTML
<!-- tabs -->
<ul class="tabs currenttab-info">
<li id="tab-info" class="info"><strong>Information</strong></li>
<li id="tab-write" class="write"><strong>Write Feedback</strong></li>
<li id="tab-read" class="read"><strong>Read Feedback</strong></li>
</ul>
Javascript
// send '.currenttab-x' to '.tabs' and remove '.currenttab-y' + '.currenttab-z'
// when LI #tab-X is clicked ...
$( '#tab-info' ).click(function() {
// ... find the UL and remove the first possible conflicting class
$('.tabs').removeClass("currenttab-read");
// ... find the UL and remove the other possible conflicting class
$('.tabs').removeClass("currenttab-write");
// ... find the UL and add the class for this LI
$('.tabs').addClass("currenttab-info");
});
// ... repeat ...
$( '#tab-write' ).click(function() {
$('.tabs').removeClass("currenttab-info");
$('.tabs').removeClass("currenttab-read");
$('.tabs').addClass("currenttab-write");
});
$( '#tab-read' ).click(function() {
$('.tabs').removeClass("currenttab-info");
$('.tabs').removeClass("currenttab-write");
$('.tabs').addClass("currenttab-read");
});
This actually seems to be working, BUT it's a fumbling solution and I am sure there is a better way. Some of you jQuery ninjas will know how to put this functionality together really elegantly, any help?
Also I would like to add onto this so that the clicked LI is also given a class to show it is selected while the other LIs are stripped of any such class. The same sort of thing I already am doing for the UL; I can see how to do that with my awkward approach, but it will mean even more and more lines of messy code. If your improvement also included a way to do change classes of the LIs I'd appreciate it
FYI: I'm using jQuery Tools Tabs with this so there is more jQuery then I showed, but only the bit I quoted seems relevant.
html
I will remove ids of li if you are not using it for other purposes.
<ul class="tabs currenttab-info">
<li class="info"><strong>Information</strong></li>
<li class="write"><strong>Write Feedback</strong></li>
<li class="read"><strong>Read Feedback</strong></li>
</ul>
jQuery
$('.tabs li').click(function() {
var $li = $(this);
$li.addClass('current').siblings().removeClass('current'); // adds a current class to the clicked li
var $ul = $li.parent();
$ul.removeClass("currenttab-info currenttab-read currenttab-write")
.addClass("currenttab-" + this.class ); // assuming li only holds one class e.g. class="write"
});
You can just do something like this:
$('.tabs > li').click(function() {
$(this).parent().attr('class', 'tabs').addClass('currenttab-'+$(this).attr('class'));
});
$("UL.tabs LI A").bind('click',function(e){ //bind a Click-Event handler to the Links
var $target = $(e.target); //the jQuery-Object-Reference to the clicked target ( $(this) should work too)
var LIClasses = $target.parents('LI').attr('class'); //A list of all Classes the parrent LI of the clicked Link have
$target
.parents('UL.tabs')
//now you can remove and add classes to the parent "UL.tabs"
.removeClass('...')
.addClass('...')
.end() //after .end() the chain for .parents-match is broken
.parents('LI')
//here you can add and remove classes from the parent LI
.removeClass('...')
.addClass('...')
.end() //after .end() the chain for .parents-match is broken
;
});
Notes:
jQuery is chainable.
.removeClass() and .addClass() can work with multiple classnames at the same time by speration with a space (like .removeClass('class1 class2'))
The full solution:
var relevantClasses = ['read','write','info'];
$("UL.tabs LI A").bind('click',function(e){
var $target = $(e.target);
var relevantClass = '';
for( var cl in $target.parents('LI').attr('class').split(' ') )
if( jQuery.inArray(relevantClasses , cl) > -1 ){
relevantClass = cl;
break;
}
$target
.parents('UL.tabs')
.removeClass(jQuery.map(relevantClasses , function (className) { return 'currenttab-' + className; }).join(' '))
.addClass('currenttab-'+relevantClass )
.end()
;
});
First of all you can chain the method calls...
$('.tabs').removeClass("currenttab-read currenttab-write").addClass("currenttab-write");
This would make the code much cleaner...
EDIT: I'll try such things in Fiddle http://jsfiddle.net/JvtAz/