I have a tabbed setup on the page and I want to automatically make corresponding menu tab highlighted as well as corresponding content div show depending on # hash.
Example:
http://design.vitalbmx.com/user_menu/member_profile_so.html -- no hash, opens 1st tab
http://design.vitalbmx.com/user_menu/member_profile_so.html#setup -- #setup, should open "Setup" tab
As you can see it works for highlighting "Setup" tab. But content div does not change.
The script is below:
var tab_content_current = 1;
switch (window.location.hash) {
case '#activity': tab_content_current = 1; break;
case '#friends': tab_content_current = 2; break;
case '#photos': tab_content_current = 3; break;
case '#videos': tab_content_current = 4; break;
case '#setup': tab_content_current = 5; break;
case '#forum': tab_content_current = 6; break;
case '#blog': tab_content_current = 7; break;
case '#comments': tab_content_current = 8; break;
case '#favorites': tab_content_current = 9; break;
case '#profile-comments': tab_content_current = 10; break;
default: tab_content_current = 1;
}
if (tab_content_current != 1) {
change_active_tab (tab_content_current);
}
function tabs_toggle (id) {
if (id != tab_content_current) {
change_active_tab (id);
tab_content_current = id;
}
}
function change_active_tab (id) {
$j('.profile_tabs li').removeClass('active');
if (id < 8) $j('.profile_tab_'+id).addClass('active');
$j('.profile_content').hide();
$j('#profile_content_'+id).fadeIn();
}
Note that it works when you actually click menu tabs.
Any help to fix this problem would be greatly appreciated.
Move the script to the very bottom of the page, after the profile_content divs. That way they will be in the DOM before the scripts run. It is also best to put scripts at the bottom of the page for speed reasons.
That part of the code is not inside a jQuery ready() call, so the DOM is not yet loaded when it runs.
EDIT: The reason the tabs work, is that the script appears to be in the middle of the HTML content. The tas come before the script, and the content comes after. So that tabs are loaded, and the content sections are not.
Do this:
$(document).ready(function() {
var tab_content_current = 1;
switch (window.location.hash) {
case '#activity': tab_content_current = 1; break;
case '#friends': tab_content_current = 2; break;
case '#photos': tab_content_current = 3; break;
case '#videos': tab_content_current = 4; break;
case '#setup': tab_content_current = 5; break;
case '#forum': tab_content_current = 6; break;
case '#blog': tab_content_current = 7; break;
case '#comments': tab_content_current = 8; break;
case '#favorites': tab_content_current = 9; break;
case '#profile-comments': tab_content_current = 10; break;
default: tab_content_current = 1;
}
if (tab_content_current != 1) {
change_active_tab (tab_content_current);
}
function tabs_toggle (id) {
if (id != tab_content_current) {
change_active_tab (id);
tab_content_current = id;
}
}
function change_active_tab (id) {
$j('.profile_tabs li').removeClass('active');
if (id < 8) $j('.profile_tab_'+id).addClass('active');
$j('.profile_content').hide();
$j('#profile_content_'+id).fadeIn();
}
});
Or just place the script at the end of the page. Good idea to use ready() anyway, though.
Try setting your <li> elements up like this:
<ul class="profile_tabs light">
<li class="profile_tab_1 active">Activity</li>
you can more easily write some jQuery to tab like so:
var tab_content_current = 1;
function GetIndex($obj) { return $(this).parent().children().index($obj); }
$j(function(){
$j(".profile_tabs li").click(function(e){
e.preventDefault();
change_active_tab(GetIndex(this) + 1)
});
function change_active_tab (id) {
tab_content_current = id;
$j('.profile_tabs li').removeClass('active');
if (id < 8) $j('.profile_tab_'+id).addClass('active');
$j('.profile_content').hide();
$j('#profile_content_'+id).fadeIn();
}
var hash = window.location.hash;
if (hash != null && hash != "")
{
var $li = $(".profile_tabs li a[href=" + hash + "]");
change_active_tab(GetIndex($li) + 1)
}
});
Related
I want to focus my dropdown elements from keyboard (up and down keys).
My code:
var matches = document.querySelectorAll("div.dropdown-content > a");
var i = 0;
var focused = matches[i];
document.onkeydown = function(e) {
switch (e.keyCode) {
case 37:
i++;
focused.focus();
break;
case 38:
i--;
focused.focus();
break;
}
};
But it's actually not working. Console does not report any errors.
Arrow key up is 38, down is 40, also check i range between 0, nodes.length
const matches = document.querySelectorAll('div.dropdown-content > a');
let i = 0;
let focused;
if (matches.length > 0) {
matches[i].focus();
focused = matches[i];
document.onkeydown = function(e) {
e.preventDefault();
switch (e.keyCode) {
case 40:
if (i < matches.length - 1) {
i++;
}
matches[i].focus();
focused = matches[i];
break;
case 38:
if (i > 0 ) {
i--;
}
matches[i].focus();
focused = matches[i];
break;
}
};
}
a { display: block; }
<div class="dropdown-content">
Link
Link
Link
Link
Link
</div>
You keep focusing the same element, focused is not updated when i changes.
Also, the keycode for down arrow is 40, not 37.
Finally, you should check that i is always between 0 and matches.length - 1.
var matches = document.querySelectorAll("div.dropdown-content > a");
var i = 0;
document.onkeydown = function(e) {
switch (e.keyCode) {
case 40:
if(i < matches.length - 1) i++;
matches[i].focus();
break;
case 38:
if(i > 0) i--;
matches[i].focus();
break;
}
};
You can also focus the first item when you reached the last one and vice versa :
document.onkeydown = function(e) {
switch (e.keyCode) {
case 40:
i = (i + 1) % matches.length;
matches[i].focus();
break;
case 38:
i = Math.abs(i - 1 + matches.length) % matches.length;
matches[i].focus();
break;
}
};
How I get out from the loop if switch-case implemented (there is a switch inside the loop).
function playInbestPlace() {
console.log("hello from playInbestPlace ")
findEmptyarea();
for (var i = 0; i < indexOfEmpty.length; i++) {
var elem = indexOfEmpty[i];
switch (elem) {
case 0:
cells[elem].childNodes[0].append("o");
break;
case 2:
cells[elem].childNodes[0].append("o");
break;
case 4:
cells[elem].childNodes[0].append("o");
break;
case 6:
cells[elem].childNodes[0].append("o");
break;
case 8:
cells[elem].childNodes[0].append("o");
break;
}
}
}
I want it to get out if any case valid.
you can add a variable found and break out of the loop if it's true :
function playInbestPlace() {
console.log("hello from playInbestPlace ")
findEmptyarea();
for (var i = 0; i < indexOfEmpty.length; i++) {
var elem = indexOfEmpty[i];
var found = false; // initial found is false
switch (elem) {
case 0:
cells[elem].childNodes[0].append("o");
found = true;
break;
case 2:
cells[elem].childNodes[0].append("o");
found = true;
break;
case 4:
cells[elem].childNodes[0].append("o");
found = true;
break;
case 6:
cells[elem].childNodes[0].append("o");
found = true;
break;
case 8:
cells[elem].childNodes[0].append("o");
found = true;
break;
}
if(found) // break out if it's true
break;
}
}
You could use a flag variable to break from the loop when some condition is verified.
function playInbestPlace() {
console.log("hello from playInbestPlace ");
findEmptyarea();
var keepOnLooping = true;
for (var i = 0; keepOnLooping && i < indexOfEmpty.length; i++) {
if (elem % 2 === 0) {
cells[elem].childNodes[0].append("o");
keepOnLooping = false;
}
}
}
I've also added epascarello optimization in my answer.
I have some code like below:
for (var i = 0; i < $scope.Option.length; i++) {
var option = $scope.Option[i].Code;
if (option == "A") {
$scope.aSelected = true;
break;
}
}
for (var i = 0; i < $scope.Option.length; i++) {
var option = $scope.Option[i].Code;
if (option == "B") {
$scope.bSelected = true;
break;
}
}
Is it possible to right this in a switch statement like below:
for (var i = 0; i < $scope.Option.length; i++) {
var option = $scope.Option[i].Code;
switch (option) {
case "A":
$scope.aSelected = true;
break;
case "B":
$scope.bSelected = true;
break;
default:
console.log('unrecognized option');
}
}
Is this actually incorrect in the switch case because the first option may be A which will break out of the loop and then for example if 'B' was the option in a later position of the collection it would never get bSelected = true;
It's correct because the BREAK inside of SWITCH will break out of it, not the whole FOR loop, and therefore it will check for B too.
I want to simplify this long jquery/javascript code, can you help me? I still learn :)
Here's my jquery code:
$('.pagination-link').click(function() {
setTimeout(function() {
currentAnchor = $('body').attr('class');
switch (currentAnchor) {
case 'active-slide-1':
$('#rond').removeClass().addClass('rond1').animate();
break;
case 'active-slide-2':
$('#rond').removeClass().addClass('rond2').animate();
break;
case 'active-slide-3':
$('#rond').removeClass().addClass('rond3').animate();
break;
case 'active-slide-4':
$('#rond').removeClass().addClass('rond4').animate();
break;
case 'active-slide-5':
$('#rond').removeClass().addClass('rond5').animate();
break;
case 'active-slide-6':
$('#rond').removeClass().addClass('rond6').animate();
break;
case 'active-slide-7':
$('#rond').removeClass().addClass('rond7').animate();
break;
case 'active-slide-8':
$('#rond').removeClass().addClass('rond8').animate();
break;
default:
$('#rond').removeClass();
}
}, 50);
});
$('.overlay-menu > ul > li > a').click(function() {
setTimeout(function() {
currentAnchor = $('body').attr('class');
switch (currentAnchor) {
case 'active-slide-1':
$('#rond').removeClass().addClass('rond1').animate();
break;
case 'active-slide-2':
$('#rond').removeClass().addClass('rond2').animate();
break;
case 'active-slide-3':
$('#rond').removeClass().addClass('rond3').animate();
break;
case 'active-slide-4':
$('#rond').removeClass().addClass('rond4').animate();
break;
case 'active-slide-5':
$('#rond').removeClass().addClass('rond5').animate();
break;
case 'active-slide-6':
$('#rond').removeClass().addClass('rond6').animate();
break;
case 'active-slide-7':
$('#rond').removeClass().addClass('rond7').animate();
break;
case 'active-slide-8':
$('#rond').removeClass().addClass('rond8').animate();
break;
default:
$('#rond').removeClass();
}
}, 50);
});
$(window).mousewheel(function() {
setTimeout(function() {
currentAnchor = $('body').attr('class');
switch (currentAnchor) {
case 'active-slide-1':
$('#rond').removeClass().addClass('rond1').animate();
break;
case 'active-slide-2':
$('#rond').removeClass().addClass('rond2').animate();
break;
case 'active-slide-3':
$('#rond').removeClass().addClass('rond3').animate();
break;
case 'active-slide-4':
$('#rond').removeClass().addClass('rond4').animate();
break;
case 'active-slide-5':
$('#rond').removeClass().addClass('rond5').animate();
break;
case 'active-slide-6':
$('#rond').removeClass().addClass('rond6').animate();
break;
case 'active-slide-7':
$('#rond').removeClass().addClass('rond7').animate();
break;
case 'active-slide-8':
$('#rond').removeClass().addClass('rond8').animate();
break;
default:
$('#rond').removeClass();
}
}, 50);
});
I don't know if I have to use php to get the end of currentAnchor and put it as a parameters. Thank you for your help !
EDIT: I found that the default case is not necessary in my code. But I learn something new if I had my defaut case was important. So, here it's the new one:
function rondClass() {
setTimeout(function() {
currentAnchor = $('body').attr('class');
var currentClass = currentAnchor.replace('active-slide-', 'rond');
$('#rond').removeClass().addClass(currentClass).animate();
}, 50);
}
$('.pagination-link').click(rondClass);
$('.overlay-menu > ul > li > a').click(rondClass);
$(window).mousewheel(rondClass);
Thank you everyone !
You could just replace active-slide- with rond.
var currentAnchor = $('body').attr('class');
var newClass = currentAnchor.replace('active-slide-', 'rond');
$('#rond').removeClass().addClass(newClass).animate();
To handle the default case, you can handle this using indexOf or match:
// indexOf version
if (currentAnchor.indexOf('active-slide-') !== 0) {
$('#rond').removeClass();
} else {
$('#rond').removeClass().addClass(newClass).animate();
}
// match version
if (!currentAnchor.match(/^active-slide-/)) {
$('#rond').removeClass();
} else {
$('#rond').removeClass().addClass(newClass).animate();
}
Replace switch/case with programmatic approach and extract function to avoid code duplication.
var onClick = function() {
setTimeout(function() {
currentAnchor = $('body').attr('class');
var slide = currentAnchor.match(/active\-slide\-(\d)/);
if (slide) {
$('#rond').removeClass().addClass('rond' + slide[1]).animate();
} else {
$('#rond').removeClass();
}
}, 50)
})
$('.overlay-menu > ul > li > a').click(onClick);
$('.pagination-link').click(onClick);
I'm trying to use jquery cookies to store the state of a tree menu between page loads, for some reason the below code does not seem to create a cookie inside the switch statement. Using the cookie code outside of the switch statement works fine. I'm not too great with JS so it could be a simple issue with my switch,
intImage = 2;
var catCookie = jQuery.cookie('catCookie');
if(catCookie == 'left')
{
intImage = 1;
};
if(catCookie == 'down')
{
intImage = 2;
};
function swapImage() {
switch (intImage) {
case 1:
intImage = 2
document.getElementById(".giftarrow").src = "http://www.domain.com/left-arrow.png";
jQuery.cookie('catCookie', 'left')
return(false);
case 2:
intImage = 1
document.getElementById(".giftarrow").src = "http://www.domain.com/down-arrow.png";
jQuery.cookie('catCookie', 'down')
return(false);
}
}
any help is greatly appreciated.
You seem to be missing some semicolons:
switch (intImage) {
case 1:
intImage = 2;
$('.giftarrow').attr('src', 'http://www.gracecole.co.uk/shop/skin/frontend/default/default/images/left-arrow.png');
jQuery.cookie('catCookie', 'left');
return(false);
case 2:
intImage = 1;
$('.giftarrow').attr('src','http://www.gracecole.co.uk/shop/skin/frontend/default/default/images/down-arrow.png');
jQuery.cookie('catCookie', 'down');
return(false);
}