I am using the following js which works great for hiding and showing content when one of 5 tabs is clicked. Works great but my question is, how could i adjust the code so that when a tab's content is currently being displayed, the tab has an active class. The hover class works well and so does everything else besides the active class. Any help is hugely appreciated:
$(window).ready(function() {
$('#infotab').click(function() {
$(document).find('.tabcontent').hide();
$('.infotabcontent').show();
$(document).find('.top-nav2-menu li').removeClass('tabactive');
$('#infotab').addClass('tabactive');
$('#reviewtab').removeClass('tabactivelast');
});
$('#findingtab').click(function() {
$(document).find('.tabcontent').hide();
$('.findingtabcontent').show();
$(document).find('.top-nav2-menu li').removeClass('tabactive');
$('#findingtab').addClass('tabactive');
$('#reviewtab').removeClass('tabactivelast');
document.getElementById('frame1').contentDocument.location.reload(true);
});
$('#streetviewtab').click(function() {
$(document).find('.tabcontent').hide();
$('.streetviewtabcontent').show();
$(document).find('.top-nav2-menu li').removeClass('tabactive');
$('#streetviewtab').addClass('tabactive');
$('#reviewtab').removeClass('tabactivelast');
document.getElementById('frame2').contentDocument.location.reload(true);
});
$('#videotab').click(function() {
$(document).find('.tabcontent').hide();
$('.videotabcontent').show();
$(document).find('.top-nav2-menu li').removeClass('tabactive');
$('#videotab').addClass('tabactive');
$('#reviewtab').removeClass('tabactivelast');
});
$('#reviewtab').click(function() {
$(document).find('.tabcontent').hide();
$('.reviewtabcontent').show();
$(document).find('.top-nav2-menu li').removeClass('tabactive');
$('#reviewtab').addClass('tabactivelast');
});
});
Your code is a pain ...
$(window).ready(function() { should be $(function() {
which is a shorthand for $(document).ready(function(){
In your HTML assign a class class="tab" to all your id="***tab" elements
Cache your elements collections $('.tabcontent') and $('.top-nav2-menu li')
use the $(this) selector
Than this is all you need:
$(function(){ // DOM is now ready
// Cache your selectors
var $tabCont = $(".tabcontent"),
$topNavLi = $(".top-nav-menu li"),
$tabRev = $('#reviewtab');
$('.tab').click(function() {
var myId = this.id;
if(myId=="findingtab"){
$('#frame1')[0].contentDocument.location.reload(true);
}
if(myId=="streetviewtab"){
$('#frame2')[0].contentDocument.location.reload(true);
}
$tabCont.hide();
$("."+ myId +"content").show();
$(this).addClass('tabactive').siblings().removeClass('tabactive');
$tabRev.removeClass('tabactivelast');
if(myId=="reviewtab"){
$(this).addClass('tabactivelast');
}
});
});
With something like:
function deactivateAllTabs(){
$('#infotab, #findingtab, #streetviewtab, #videotab, #reviewtab').removeClass('tabactive');
}
Then, prior to adding your tabactive class you'd call this method:
So, for example, instead of:
$('#infotab').addClass('tabactive');
do this:
deactivateAllTabs();
$('#infotab').addClass('tabactive');
repeate this for all your click handlerss
This way, the active tab will always have a tabactive class
I don't know your DOM structure, since you didn't post it, but I'm assuming that every tab has an identical class, "tabcontent", from what you've posted. If so, you could do something like this inside your function:
$('.tabcontent').removeClass('.tabactive'); // removes class from all tabs
$('#sometab').addClass('.tabactive'); // adds class to specific tab
Then you could show or hide using just some CSS, like this:
.tabcontent { display: none; }
.tabactive { display: block; }
IMHO you'd also be better off using a single function for all of your tabs so they get the same treatment. Easier to maintain. e.g. Give each tab bar item that you click on to see the tab a data attribute with the id of the div you want to display, and you could expand on something like this (untested but hopefully you get the gist):
$('.tab').click(function() {
$('.tabcontent').removeClass('.tabactive');
$($(this).data('tabcontent')).addClass('.tabactive');
});
Related
I'm creating a simple tile game for class. What I am trying to do is:
Inside the parent div is a child class 'square' that if clicked, the square is appended to the parent with the class 'empty'
I need the parent that had the child to now be class 'empty' and the now occupied parent to have the class 'full'
The current problem I'm having is the children keep appending to the class the class 'empty', and that class is not switching.
I looked here: Get all elements without child node in jQuery
and here: http://api.jquery.com/toggleclass/
and here is my code pen : http://codepen.io/super996/pen/vyQyxN
// when page loads all parent divs are clickable to .empty class div
$('document').ready(function () {
for (let i = 0; i < $('.parent').children().length; i += 1) {
$('.square').click(function () {
$(this).appendTo('.empty');
});
}
});
$('parent:has(.full)').click(function (event) {
$(event.target).toggleClass('.empty', true);
});
});
if ($('.square').click === true) {
//parent of sqaure gets class empty and destination of square
//parent gets class full
}
EDIT: I'm in he process of trying this..
if ($('.full:first-child').click(function (){
$('.full:first-child').removeClass('.')
});
this is my complete javascript code.
maybe you can try replace your script with this
// when page loads all parent divs are clickable to .empty class div
$('document').ready(function () {
$('.square').click(function () {
var parent = $(this).parent('div');
$(this).appendTo('.empty');
$('.empty').addClass('full').removeClass('empty');
parent.addClass('empty').removeClass('full');
});
});
So I am a little fuzzy on how you're trying to accomplish this, but it looks like you want to switch classes from .full to .empty when a full tile is clicked and add the .full class to the empty tile. For this you can try by delegating events to the children of #board
Try:
$(document).ready(function(){
var $board = $('#board'); //Cache the board
$board.on('click', 'div.full', function(){
$board.find('div.empty').removeClass('empty').addClass('full');
$(this).addClass('empty').removeClass('full');
});
});
This should help you without doing the entire assignment for you ;)
Now all you need to do is figure out where to switch from .addClass and .removeClass to .appendTo and .empty
running into issues of trying to have only 1 div toggle instead of them all toggle. I've tried using next() and setting the selector to the children as opposed to the parent element, but then it won't toggle open at all.
FIDDLE:
http://jsfiddle.net/L415g07n/2/
What I am specifically trying to accomplish?
Have the selected div toggle when .toggle is clicked instead of all of them being toggled at once.
var c1 = $("#o");
var c2 = $("#t");
var c3 = $("#th");
$(document).ready(function () {
$(c1).hide(0).delay(500).fadeIn(1500);
$(c2).hide(0).delay(1500).fadeIn(1500);
$(c3).hide(0).delay(2500).fadeIn(1500);
});
var content = $("#main .column .body");
$(content).hide();
var t1 = $(".toggle");
$(t1).click(function () {
$(content).slideToggle('slow');
$(t1).toggleClass("toggle");
$(t1).toggleClass("toggle-d");
});
Try to use this object and traverse to the required nodes,
$(t1).click(function () {
$(this).toggleClass("toggle")
.toggleClass("toggle-d")
.parent().next('.body').slideToggle('slow');
});
DEMO
jQuery's $(this) alows you to apply your effects on the current element. Here's the correct, shorter and simpler version of your code:
$(document).ready(function () {
$(".column, .body").hide(); // you should put this in your CSS ( .column, .body { display: none; } )
$(".column").each(function(index) {
$(this).delay(400*index).fadeIn(300);
});
$(".toggle").click(function () {
$(this).toggleClass("toggle").toggleClass("toggle-d").parent().next(".body").slideToggle();
});
});
Notice, how you can even improve the part when your divs fade in, by reffering to them with a class name instead of id by using $(this) and .each().
I think w3schools explains $(this) quite nicely.
I have my menu like this:
https://jsfiddle.net/23r4q610/
And my code to change the selected menu button like below:
$('#bluebutton').click(function () {
$('.testul li').removeClass('selectedred selectedpurple selectedgreen selectedorange');
$('#bluebutton').addClass('selectedblue');
});
$('#redbutton').click(function () {
$('.testul li').removeClass('selectedblue selectedpurple selectedgreen selectedorange');
$('#redbutton').addClass('selectedred');
});
$('#purplebutton').click(function () {
$('.testul li').removeClass('selectedblue selectedred selectedgreen selectedorange');
$('#purplebutton').addClass('selectedpurple');
});
$('#greenbutton').click(function () {
$('.testul li').removeClass('selectedblue selectedred selectedpurple selectedorange');
$('#greenbutton').addClass('selectedgreen');
});
$('#orangebutton').click(function () {
$('.testul li').removeClass('selectedblue selectedred selectedpurple selectedgreen ');
$('#orangebutton').addClass('selectedorange');
});
Ofcourse this is bad code since it could be written much shorter. Should I go about this using just numbers so I can do some foreach, or is there a better way to do this?
This can be condensed by adding a generic click event on all buttons by using [id*="button"]. Then grab the relevant color from the nested anchor.
$('[id*="button"]').click(function(){
$('.testul li').removeClass();
$(this).addClass('selected'+$('a',this).attr('class'));
});
or
$('li').click.../*this would be the same as above*/
fiddle
In this particular case, there doesn't appear to be a good reason to add and remove classes. Just change the background color instead of adding and removing a class to do so.
$(this).css("background-color", "red");
I would avoid hard-coding the color names into the HTML IDs. Rather use a CSS class name like "selected" and describe in your CSS what that should look like. Example:
<li id="home-button" class="color-button">Home
CSS:
#home-button.selected,
#home-button:hover {
background: -webkit-linear-gradient(#78b1ff, #4881dc);
}
JS:
$('.color-button').click(function () {
$(this).toggleClass("selected").siblings(".color-button").removeClass("selected");
}
This way color information (presentation) is separated from semantic information (like "home") and JS code is daramtically shorter.
Note: this is just an advice, I have not tested it but should give you a good point to start.
You can reduce the code to only 1 click binding. Where when an element is clicked, class from all the li's is removed and then on the current clicked li, selected class is added.
$(".testul > li").click(function(){
$('.testul li').removeClass('selectedred selectedpurple selectedgreen selectedorange selectedblue');
var color = $(this).attr("id").replace("button","");
$('#'+color+'button').addClass('selected'+color);
});
Here is the updated fiddle - https://jsfiddle.net/23r4q610/2/
I have a default class. When the icon has been clicked, the default class will be removed and replaced with the new one, then when the icon has been clicked again, then the old class will be added again, then the new class will be removed. It should be changed every time the icon is clicked. It's closed to .toggleClass(), but should show/hide and replace the class.
Here is my js code
var MenuIcon = $('.menu-icon-plus'),
MenuSidebar = $('.sidebar');
MenuIcon.click(function(){
if ($(MenuSidebar).hasClass('test')) { //existing class
$(MenuSidebar).removeClass('test');
} else {
$(MenuSidebar).addClass('test2'); // replacement of old class
}
Add the two classes to toggleClass("default special") to swap them:
$("button").on("click", function(){
$(this).toggleClass("default special");
});
.default{
background:lime;
font-size:2em;
}
.special{
background:gold;
/* I don't have font size */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="default">TEST</button>
P.S: If you wanted to only change the background, than toggleClass("special") would suffice.
Or, again using only .toggleClass("special") you could set directly in CSS the reset styles, but that just complicates stuff. It clearly depends on the use case.
Try this. Replace the classes as per your requirement.
$(document).on('click', '.oldclass', function() {
$(this).removeClass('oldclass').addClass('newclass');
});
$(document).on('click', '.newclass', function() {
$(this).removeClass('newclass').addClass('oldclass');
});
I have a list of a list that uses jquery toggle and slideToggle so that when items are clicked on, explanatory text slides out and the class changes on the h3. The html for the items looks like:
<li><h3>What do I know about javascript?</h3>
<div class="check_list_wrap feature1">Not a lot, apparently.</div>
</li>
I included the jquery files and then write this in the header:
<script type="text/javascript">
$(function() {
$("#listfeatures h3 a").toggle(function(){
$(this).addClass("check_list_selected");
}, function () {
$(this).removeClass("check_list_selected");
});
$("#listfeatures h3 a").click(function() {
$("."+this.id).slideToggle('fast');
return false;
});
});
</script>
This makes it so that if a link is clicked on, it will toggle the class change of the h3, the display:block/display:inline and the sliding out of the div. It works fine.
BUT, now I want it so that with a url like index.php#feature1, the toggling for that list item will be activated as if it'd been clicked on. I know I need to use location.hash but I'm not sure how to do that. Where should I start?
location.hash contains everything in the URL including and after the hash (#) mark. So, if went to index.php#feature1 and wanted the div with id "feature1" to show on load, you could do
$(document).ready(function() {
if(location.hash) {
var id = location.hash.slice(1); //Get rid of the # mark
var elementToShow = $("#" + id); //Save local reference
if(elementToShow.length) { //Check if the element exists
elementToShow.slideToggle('fast'); //Show the element
elementToShow.addClass("check_list_selected"); //Add class to element (the link)
}
}
});