The active class isn't working and I've tried body On-load click trigger and obviously show tab using id and many other ways, however nothing seems to be working. I have hashed the URL to enable tabs to be linked individually in the search. Any help is much appreciated.
JS: to hash the URL and jump to tab
// jump to tab if it exists
if (location.hash) {
$('a[href=' + location.hash + ']').tab('show');
}
// add tab hash to url to persist state
$(document.body).on("shown.bs.tab", function(e){
location.hash = e.target.hash;
});
});
JS: To go to tab home (not working)
$("document").ready(function(){
$("#home").trigger("click");
});
HTML:
<div class="col-xs-5 col-md-2 nopadding">
<nav class="nav-sidebar">
<ul class="nav tabs">
<li class="lead3">Home </li>
<li class="lead3">tab1</li>
<li class="lead3"><a href="#tab3" data-toggle="tab" >tab3</a></li>
<li class="lead3"> Contact </li>
</ul>
</nav>
tab-pane:
<div class="tab-pane active fade text-style" id="home"> . .. </div>
What you expect from this line?
$("home").trigger("click");
I suppose Jquery can't find element here $("home"). You could evaluate it in console for check.
if you are going to find element with class 'home' or id 'home' then you should use $(".home") or $("#home") properly.
It looks like your Document Ready event doesn't work.
Try remove the quotes around the $("document").
A shorter method for this event is as follows:
$(function() {
});
I know that this is very late but I'd like to post my solution since this was something that I was stuck on as well. There's an important subtlety that I think is easy to miss. You want to trigger the click on the <a> tag inside the nav, not the actual panel. Remember you click on the tab not on the panel to trigger it into view. So to get the correct tab to show when the user navigates to /my/path#home you want to bind on the hashchange event and click the correct element. See https://stackoverflow.com/a/680865/5262119 for more info on binding to the hashchange event.
$(window).bind('hashchange', function(event){
var hash = window.location.hash;
// get the actual anchor tag that links to the panel
var $matchingAnchor = $('nav a[href^="' + hash + '"');
if ($matchingAnchor) $matchingAnchor.click();
});
And assuming you want to restrict this to trigger only a certain page then you can add a location check:
$(window).bind('hashchange', function(event){
var path = window.location.pathname;
var hash = window.location.hash;
var $matchingAnchor = $('nav a[href^="' + hash + '"');
var contextRegex = /my\/page/;
var correctPage = contextRegex.test(path);
if (correctPage && $matchingAnchor) $matchingAnchor.click();
});
I imagine you also want to make sure that clicks on the tabs update the hash in the URL window so bind to the tabs event:
$('nav a').on('click',function() {
var $a = $(this);
var hash = $a.attr("href");
window.location.hash = hash;
});
This would go inside your ready function. You will also have to make sure that the function that triggers the click happens when the page first loads.
Complete solution:
$(document).ready(function() {
// Declare clickback function
function triggerTabClick() {
var path = window.location.pathname;
var hash = window.location.hash;
var $matchingAnchor = $('nav a[href^="' + hash + '"');
var contextRegex = /my\/page/; // or whatever you want this to be
var correctPage = contextRegex.test(path);
if (correctPage && $matchingAnchor) $matchingAnchor.click();
}
// Trigger it when the hash changes
$(window).bind('hashchange', triggerTabClick);
// Trigger it when the page loads
triggerTabClick();
// Hook into click for tabs to make sure hash is updated on click
$('nav a').on('click',function(event){
event.preventDefault();
var $a = $(this);
var hash = $a.attr("href");
var window.location.hash = hash;
})
})
Related
I'm new to jQuery and want to highlight div's if the div's anchor id is set.
I currently have this construct which only works on page load with an valid anchor attached.
$(document).ready(function(){
var divpost = window.location.hash.substr(1);
if($.isNumeric(divpost)){
$('#reply_' + divpost).css('background-color', '#EDA2FF');
}
});
This works only on page load with a set anchor. How can I make this more dynamic so the script executes whenever the anchor changes?
jQuery can hook into the hashchange event so you can do this:
$(window).on('hashchange', function(e){
var divpost = window.location.hash.substr(1);
if($.isNumeric(divpost)){
$('#reply_' + divpost).css('background-color', '#EDA2FF');
}
});
You can make it a function and call it with every update.
function updateAnchors() {
var divpost = window.location.hash.substr(1);
if($.isNumeric(divpost)){
$('#reply_' + divpost).css('background-color', '#EDA2FF');
}
}
Then call updateAnchors() when more anchors are loaded.
http://jsfiddle.net/78QPs/
This is the Javascript
$(document).ready(function() {
$(".tab_content").hide();
$(".tab_content:first").show();
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active");
$(this).addClass("active");
$(".tab_content").hide();
var activeTab = $(this).attr("rel");
$("#"+activeTab).fadeIn();
});
});
I have used the above to make my tabs but I want to link to tabs2 & tab3 in my above example from another webpage using a href. Any other way other than using Jquery UI like javascript?
In short, How do I create a link to a tab directly from another page and within the page from the above example?
I guess that is 1) Listen for the Hash, and 2) trigger the click of the relevant 'tab'.
Now Im not 100% on the support for this event listener from jquery - but I'll add it it.
/* listen for the anchor hashtag change */
$(window).on('hashchange', function() {
/* trigger the click of the tab with the matching rel */
var _rel = document.location.hash.
$("li[rel="+_rel.substring(1)+"]").click();
});
Or use this listener of sorts which is native, ( I use it but I might need to update to the above if it works out ).
var _currhash;
function anchorWatch() {
if(document.location.hash.length>0) {
/* only run if 'hash' has changed */
if(_currhash!==document.location.hash) {
_currhash = document.location.hash;
$("li[rel="+ _currhash.substring(1)+"]").click();
}
}
}
setInterval(anchorWatch,300);
Here is a demo and code of something I added on another q that could be relevant : - http://jsbin.com/soqopepe/1/edit
*( not using jquery tabs), but works in the same way *
Here is a demo of your code with this added :
http://jsfiddle.net/sa2Lj/
To try, http://jsfiddle.net/sa2Lj/show/#tab3
You have various options: use a hash inside your url to reference the id of your tab, and retrieve it with window.location.hash.
So let's say you have a tab with id='tab' and window.location.hash = 'tab', you can do $(window.location.hash).hide().
Another good option would be using the HTML5 history function to change the URL accordingly to the tab selected. This would also be more much nicer, I guess.
for the most cross-browser compatible solution ty something like this:
var queryString = {};
window.location.href.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
if (queryString[base.options.param]) {
var tab = $("a[href='#" + queryString[base.options.param] + "']");
tab
.closest(".tab_content")
.find("a")
.removeClass("active")
.end()
.next(".list-wrap")
.find("ul")
.hide();
tab.addClass("current");
$("#" + queryString[base.options.param]).show();
};
this assigns each tab a query string parameter value.
I'm trying to create a single webpage that replaces the content of the main div when navigation links are clicked. I've been able to implement the pushstate function to replace the div content and change the url address pretty easily. I also am able to get the content to refresh when the back/forward buttons are clicked with the popstate function. However, now I click the first link and it works fine, I click the next link and it seems to apply 2 pushstates, the 3rd click, applies 3 pushstates, etc. It seems there is a push loop occurring somewhere but not sure where it is. I am in search of some advice on how to eliminate the multiple pushstates from occurring so they aren't duplicated in my history.
HTML code:
<nav id="headerNav">
<ul>
<li><button class="navButton" id="signIn" href="./content/signIn.php" name="reply" title="SignIn">Sign In</button></li>
<li><button class="navButton" id="signUp" href="./content/registration.php" name="registration" title="Registration">Sign Up</button></li>
<li><button class="navButton" id="about" href="./content/about.php" name="settings" title="About">About</button></li>
</ul>
</nav>
<section id="mainContent">
<!-- CONTENT PAGES REPLACE HERE -->
<?php
include ('./content/start.php');
?>
</section>
Javascript
$(document).ready(function() {
if (window.history && history.pushState) {
$(".navButton").click(function(e) {
e.preventDefault();
$("#mainContent").fadeOut().load($(this).attr("href")).fadeIn();
history.pushState(null, $(this).attr("title"), $(this).attr("name"));
});
}
});
window.addEventListener('popstate', function() {
//WHEN BACK/FORWARD CLICKED CHECKS URL PATHNAME TO DETERMINE WHICH CONTENT TO PLACE IN DIV
if (location.pathname == "/index.php") {
$("#mainContent").load("./content/start.php");
} else {
$("#mainContent").load("./content" + location.pathname + ".php");
}
});
SOLVED! It was my "if" condition to test for the history API. When I removed that it eliminated the repeated history pushes. I also have my htaccess file redirecting all typed in urls to the index page that allows the pathname comparison to fire for the content. Works great but I know I'll have to address the bookmarking IF later as the site grows. For now, it functions the way I need it to so I can move forward!
window.onload = function() {
// PUSHES CORRECT CONTENT DEPENDING ON URL PATH - ENSURES BACK/FORWARD AND BOOKMARKS WORK
if (location.pathname == "/index2.php") {
$("#mainContent").load("./content/start.php");
} else {
$("#mainContent").load("./content" + location.pathname + ".php");
}
// EVEN HANDLER TO DETECT CLICK OF NAVBUTTON CLASS
$(".navButton").click(function(e) {
$(this).addClass("active");
$(".navButton").not(this).removeClass("active");
var $mainContent = $("#mainContent");
var $href = $(this).attr("href");
var $title = $(this).attr("title");
var $name = $(this).attr("name");
// REPLACES CONTENT WITH DYNAMIC TRANSITION
$mainContent.fadeOut(100, function() {
$mainContent.load($href, function() {
$mainContent.fadeIn(100);
});
});
//CHANGES DOCUMENT TITLE SINCE PUSHSTATE CAN'T DO THIS YET
document.title = $title;
// PUSHES URL CHANGE AND HISTORY STATE TO BROWSER
history.pushState('', $title, $name);
//PREVENTS DEFAULT ACTION OF NAVBUTTON
e.preventDefault();
});
// THIS EVENT MAKES SURE THAT THE BACK/FORWARD BUTTONS WORK AS WELL
window.onpopstate = function(event) {
if (location.pathname == "/index2.php") {
$("#mainContent").load("./content/start.php");
} else {
$("#mainContent").load("./content" + location.pathname + ".php");
}
};
};
I have this jquery code:
$(document).ready(function() {
$(".tabLink").each(function(){
if(location.hash) {
$(".tabLink").removeClass("activeLink");
$(location.hash+"-1").addClass("activeLink");
$(".tabcontent").addClass("hide")
$(location.hash+"-1").removeClass("hide")
} else {
$(".tablink").click(function(){
$(".tabLink").removeClass("activeLink");
$(this).addClass("activeLink");
$(".tabcontent").addClass("hide")
$(location.hash+"-1").removeClass("hide")
});
}
});
});
to switch between tabs, my html is:
Company
Contacts
<div class="tabcontent" id="companyinfo-1">
</div>
<div class="tabcontent" id="contacts-1">
</div>
when i choose another tab i have to click it twice to make the div show
here is a fiddle with the full code : http://jsfiddle.net/2SRZE/
FIDDLE
Why not keep it simple and grab the target right off the anchor link instead of the page URL?
<div class="tab-box">
Company
Contacts
</div>
<div class="tabcontent" id="companyinfo-1">
Tab 1 Content
</div>
<div class="tabcontent hide" id="contacts-1">
Tab 2 Content
</div>
$(document).ready(function() {
if(location.hash) {
// maybe do a little more validation here
setActiveLink(location.hash);
}
$('.tabLink').click(function(e) {
e.preventDefault();
var target = $(this).attr('href');
document.location.hash = target;
setActiveLink(target);
});
function setActiveLink(target) {
$(".tabLink").removeClass("activeLink");
$('a[href=' + target + ']').addClass("activeLink");
$('.tabcontent').addClass('hide');
$(target).removeClass('hide');
}
});
A comment on why you have to click twice:
When you click the tab and the event is triggered the address of the window still has not changed. On first click that would mean no hash. On subsequent clicks that would mean the hash has the value of previous clicked anchor.
Page enter: hash == ''
Click on Contacts: hash == ''
Hide content. (Company is being hided.)
Show hash + '-1' (no match as hash is empty.)
Event done, window hash changes: hash == '#contacts'
Click on #contacts: hash == '#contacts'
Hide content. (Nothing to hide).
Show hash + '-1': contacts-1 show.
Easier by example. Here the text-box is updated with hash value on each click.
Fiddle
As you can see, the hash changes too late.
So: As noted by Lucky Soni, check the target event's href value.
http://jsfiddle.net/awesome/svP3T/2/
$(document).ready(function () {
$(".tabcontent").addClass("hide");
$($(".activeLink").attr('href') + '-1').removeClass("hide");
$(".tabLink").each(function () {
var _tabLink = $(this);
var _tabLinkAttr = $(_tabLink.attr('href') + '-1');
_tabLink.click(function () {
$(".tabLink").removeClass("activeLink");
_tabLink.addClass("activeLink");
$(".tabcontent").addClass("hide");
_tabLinkAttr.removeClass("hide");
});
});
});
check this out: http://jsfiddle.net/awesome/svP3T/4/
see this too: $(window) bind hashchange how to check part hash changed?
var originalHash = window.location.hash;
$(document).ready(function () {
$(window).bind('hashchange', function () {
// remove all active
$(".tabLink").removeClass("activeLink");
$(".tabcontent").addClass("hide");
// https://stackoverflow.com/questions/7699073/window-bind-hashchange-how-to-check-part-hash-changed
var newHash = window.location.hash;
var _origHash = originalHash;
originalHash = newHash;
// log
console.log('original: ' + _origHash);
console.log('new: ' + newHash);
// update active
$('[href="' + newHash + '"]').addClass("activeLink");
$(newHash + '-1').removeClass("hide");
});
// init
$(".tabcontent").addClass("hide");
$($(".activeLink").attr('href') + '-1').removeClass("hide");
});
I have a piece of javascript that I inherited; it's being used as a tab switcher. Unfortunately it's not working. Here's the code:
$(document).ready(function(){
/* This is the back button friendly tab switcher */
var trackContainers = $('.switcher > .results');
trackContainers.hide().filter(':first').show();
$(window).bind('hashchange', function () {
var hash = window.location.hash || '#dpp';
console.log('hash: ' + hash);
trackContainers.hide();
trackContainers.filter(hash).show();
$('ul.tabs li').removeClass('active');
$('a[hash='+hash+']').parent().addClass('active');
});
$(window).trigger("hashchange").location(hash);
});
What's supposed to happen is when a specific tab is clicked, it changes the class of the li tag surrounding the clicked tab. Here's what the tab code looks like:
<div class="switcher">
<ul class="tabs">
<li class="inactive">Digital Path to Purchase</li>
<li class="inactive">Fueling Creativity</li>
<li class="inactive">Best Practices/Big Picture</li>
<li class="inactive">Shopper Insights 101</li>
<li class="inactive">Who Is Your Shopper</li>
<li class="inactive">Google Theater</li>
<li class="inactive">Understanding the Shopper</li>
<li class="inactive">Brand Activation at Retail</li>
<li class="active">Deeper Understanding of Center Store</li>
</ul>
</div>
</div>
You can see that the link called #duc has the active class on its li item. However, when I look at the script code in Firebug, it gives me an error saying hash is not defined:
Again, looking in Firebug, but this time at the console tab, it very clearly shows that hash IS defined:
Can anyone point out how it's losing its definition between the console.log and the .trigger lines?
It looks as though you are defining hash within the scope of your bind function :
$(window).bind('hashchange', function () {
var hash = window.location.hash || '#dpp';
It therefore does not exist outside of that function.
If you wanted access to that variable based off the value the window.location.hash was at the time of your hashchange event, I would create a variable outside of the bind 'hashchange' function so it has access to that variable.
var hash;
$(window).bind('hashchange', function () {
hash = window.location.hash || '#dpp';
console.log('hash: ' + hash);
trackContainers.hide();
trackContainers.filter(hash).show();
$('ul.tabs li').removeClass('active');
$('a[hash='+hash+']').parent().addClass('active');
});
$(window).trigger("hashchange").location(hash);
But the value of hash at the $(window).trigger("hashchange") line will not be set more than likely because that event may not have fired and the
hash = window.location.hash || '#dpp';
line will not have been run. I think you need to examine the workflow a little closer.
The scope of the hash variable is only the anonymous function being called in the .bind() section of the code, so doesn't exist once that function has finished executing.
you want
$(window).trigger("hashchange").location(window.location.hash);
As Anthony Grist said, the variable hash you defined in the anonymous function doesn't exist by the time you get there.
$(document).ready(function(){
/*I moved it out of the function because the var was only in existence in the bind function before. Now its going to exist still when you call it at $(window)*/
var hash = window.location.hash || '#dpp';
/* This is the back button friendly tab switcher */
var trackContainers = $('.switcher > .results');
trackContainers.hide().filter(':first').show();
$(window).bind('hashchange', function () {
//here, i'm simply changing its value, which was set on line 4 outside of the fn.
hash = window.location.hash || '#dpp';
console.log('hash: ' + hash);
trackContainers.hide();
trackContainers.filter(hash).show();
$('ul.tabs li').removeClass('active');
$('a[hash='+hash+']').parent().addClass('active');
});
$(window).trigger("hashchange").location(hash);
});