In a previous question I was provided with a small script by sean-7777 Creating a selected tab in a HTML tabstrip. It works the way he wrote it, but there are 2 issues with it.
First, while it looks for the 'current' class in the TD, it only applies it to the A tag. Second, if I add 'current' to the A tag the script does not find it, but does find it if I add it to the TD tag.
In my CSS I had to apply the :hover class to both the TD (.td1:hover) and the A (.anchor:hover) in order to get the colors I wanted. The A tag overrides the TD when it comes to the text color and that is why I had to apply the hover css to both.
I can preselect the "selected tab" by including the current class to both the TD (class='td1 bold center smaller current') and the A (class='anchor current'), but the script does not remove it when I click another tab, and as I stated above, if I only add it to the A tag the script does not find it, and if I add it only to the TD the link text does not reflect the selected color.
If I click the pre-selected tab after clicking on another tab then the script will remove the hilite when I next click on a different tab. I have been trying different things, but my lack of knowledge of this version of JavaScript is making it impossible to get anything to work properly.
So my questions are:
- How do I get the preselected tab to de-select when I click another tab?
- How do I get the 'current' class to be added and removed from both the TD and the A tags?
Edit: I finally got the cascading thing figured out. Changes in the CSS below. The script still looks for the current class in the TD but only applies it to the link text in the A tag. The pre-selected tab still remains hilited on the link text, TD de-selected, when you click another link. I believe this is also the script, and still doesn't deselect entirely until after clicking on it a second time and then clicking a different tab.
// this script by sean-7777 on stackoverflow
// https://stackoverflow.com/users/14884338/sean-7777
// https://stackoverflow.com/questions/70724038/creating-a-selected-tab-in-a-html-tabstrip
// Get all the tabs
const tabs = document.querySelectorAll("td.td1");
// Store the previous selected tab so we know which one to remove the class from
let prevSelected;
// Give each tab code
for (const tab of tabs) {
// Add a function to run when it is clicked
tab.addEventListener("click", evt => {
// Remove the current class from the last selected element
// On first run, prevSelected is not defined, so we need to check
if (prevSelected) prevSelected.classList.remove("current");
// Update prevSelected
prevSelected = evt.srcElement;
// Add the current class
evt.srcElement.classList.add("current");
});
// I added this line attempting to make the pre-selected TD get added on the initial execution
// It was this, plus using the Web Developer Tools in Firefox that enabled me to see what was going on
if (!prevSelected && tab.classList.contains('current')) prevSelected = tab;
}
table {
margin-left: auto;
margin-right: auto;
border: none;
border-spacing: 1px;
}
.bold {
font-weight: 700;
}
.center {
text-align: center;
}
.td1 {
background-color: springgreen;
font-family: Arial, sans-serif;
white-space: nowrap;
padding: 0 0 0.5pt 0;
vertical-align: middle;
}
.td1:hover, .td1 .anchor:hover {
background-color: lightyellow;
color: orange;
}
.smaller {
font-size: small;
}
.anchor {
text-decoration: none;
color: darkgreen;
}
.td1.current, .td1 .anchor.current
{
background-color: aliceblue;
color: deepskyblue;
}
<TABLE>
<TR>
<TD class='td1 bold center smaller current'> <a class='anchor current' href='Items/sheet001.htm' target='frSheet'>One-Handed Weapons</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet002.htm' target='frSheet'>Two-Handed Weapons</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet003.htm' target='frSheet'>Ranged Weapons</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet004.htm' target='frSheet'>Ammunition</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet005.htm' target='frSheet'>Shields & Armor</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet006.htm' target='frSheet'>Accessories</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet007.htm' target='frSheet'>Technicks & Magicks</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet008.htm' target='frSheet'>Augments</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet009.htm' target='frSheet'>Items</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet010.htm' target='frSheet'>The Bazaar</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet011.htm' target='frSheet'>Grimoires</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet012.htm' target='frSheet'>Bazaar Packages</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet013.htm' target='frSheet'>Shops</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet014.htm' target='frSheet'>License Board</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet015.htm' target='frSheet'>Lower Half</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet016.htm' target='frSheet'>Upper Half</a> </TD>
</TR>
</TABLE>
CodePudding user response:
I've updated your code with the following changes:
- I added
evt.preventDefault()
just for this demonstration, so that clicking on the anchor does not navigate to a non-existent page. Remove this when you copy it back to your own code. - I set
prevSelected
to thetd
element by assigning theevt
Event'scurrentTarget
property, which always refers to the element on which the event was bound (in this case,tab
). - I changed the CSS selector for your final rule from
.td1.current, .td1 .anchor.current
to.td1.current, .td1.current .anchor
. This simplifies the JavaScript, as we only need to apply thecurrent
class to the tab/td
element, not to both thetd
and thea
. As you can see when you run the code, the text is highlighted appropriately.
I'm assuming that the pages linked to (e.g., Items/sheet002.htm) have their corresponding HTML updated to have the correct classes applied? If not you'll need to add some code to check the current URL against the href
of the anchor and update the corresponding tab's classList
to add the current
class. Should be as simple as updating that final if
to be something like:
if (!prevSelected && location.href.includes(tab.querySelector('a').pathname)) {
prevSelected = tab;
tab.classList.add("current"); // this won't add it twice if it's already there.
}
// this script by sean-7777 on stackoverflow
// https://stackoverflow.com/users/14884338/sean-7777
// https://stackoverflow.com/questions/70724038/creating-a-selected-tab-in-a-html-tabstrip
// Get all the tabs
const tabs = document.querySelectorAll("td.td1");
// Store the previous selected tab so we know which one to remove the class from
let prevSelected;
// Give each tab code
for (const tab of tabs) {
// Add a function to run when it is clicked
tab.addEventListener("click", evt => {
// NOTE: The following line prevents the anchor from navigating to the
// href as expected. This is so that you can see the classes getting
// applied. Otherwise the snippet would be navigated to a non-existent
// page.
evt.preventDefault();
// Remove the current class from the last selected element
// On first run, prevSelected is not defined, so we need to check
if (prevSelected) prevSelected.classList.remove("current");
// Update prevSelected to the td element, not the anchor, no matter
// which we clicked on
prevSelected = evt.currentTarget;
// Add the current class
prevSelected.classList.add("current");
});
// I added this line attempting to make the pre-selected TD get added on the initial execution
// It was this, plus using the Web Developer Tools in Firefox that enabled me to see what was going on
if (!prevSelected && tab.classList.contains("current")) {
prevSelected = tab;
}
}
table {
margin-left: auto;
margin-right: auto;
border: none;
border-spacing: 1px;
}
.bold {
font-weight: 700;
}
.center {
text-align: center;
}
.td1 {
background-color: springgreen;
font-family: Arial, sans-serif;
white-space: nowrap;
padding: 0 0 0.5pt 0;
vertical-align: middle;
}
.td1:hover,
.td1 .anchor:hover {
background-color: lightyellow;
color: orange;
}
.smaller {
font-size: small;
}
.anchor {
text-decoration: none;
color: darkgreen;
}
.td1.current,
.td1.current .anchor {
background-color: aliceblue;
color: deepskyblue;
}
<TABLE>
<TR>
<TD class='td1 bold center smaller current'> <a class='anchor' href='Items/sheet001.htm' target='frSheet'>One-Handed Weapons</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet002.htm' target='frSheet'>Two-Handed Weapons</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet003.htm' target='frSheet'>Ranged Weapons</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet004.htm' target='frSheet'>Ammunition</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet005.htm' target='frSheet'>Shields & Armor</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet006.htm' target='frSheet'>Accessories</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet007.htm' target='frSheet'>Technicks & Magicks</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet008.htm' target='frSheet'>Augments</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet009.htm' target='frSheet'>Items</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet010.htm' target='frSheet'>The Bazaar</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet011.htm' target='frSheet'>Grimoires</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet012.htm' target='frSheet'>Bazaar Packages</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet013.htm' target='frSheet'>Shops</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet014.htm' target='frSheet'>License Board</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet015.htm' target='frSheet'>Lower Half</a> </TD>
<TD class='td1 bold center smaller'> <a class='anchor' href='Items/sheet016.htm' target='frSheet'>Upper Half</a> </TD>
</TR>
</TABLE>