I am basically making a windows xp themed portfolio and I am stumped with adding tabs to my modals. I am following a tutorial (https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role) and my issue is that when I call document.querySelectorAll('[role="tab"]') I get nothin. Using querySelector() returns null.
I was thinking that maybe it is because the tab isnt created yet until I open the modal but even then shouldn't the eventlistener check everytime something is added to the DOM? Maybe the scope is wrong but I get some errors when I put it inside the render or anywhere within the class.
Here is my component:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import "xp.css/dist/XP.css";
import Draggable from 'react-draggable';
class AboutMeModal extends Component {
render() {
return (
<Draggable
axis="both"
handle=".tabs"
defaultPosition={{x: 40, y: -80}}
position={null}
grid={[25, 25]}
scale={1}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}>
<section className="tabs" style={{width:'calc(99%)'}}>
<menu role="tablist" aria-label="Sample Tabs">
<button id="tab-1" role="tab" aria-selected="true" aria-controls="tab-A" tabIndex="0">Tab A</button>
<button id="tab-2" role="tab" aria-selected="false" aria-controls="tab-B" tabIndex="-1">Tab B</button>
<button id="tab-3" role="tab" aria-selected="false" aria-controls="tab-C" tabIndex="-1">Tab C</button>
</menu>
<article role="tabpanel" id="tab-A" aria-labelledby="tab-1">
<h3>Tab Content</h3>
<p>
You create the tabs, you would use a <code>menu role="tablist"</code> element then for the tab titles you use a <code>button</code> with the <code>aria-controls</code> parameter set to match the relative <code>role="tabpanel"</code>'s element.
</p>
<p>
Read more at <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role" target="_blank">MDN Web docs - ARIA: tab role</a>
</p>
</article>
<article role="tabpanel" id="tab-B" aria-labelledby="tab-2" hidden>
<h3>More...</h3>
<p>This tab contains a GroupBox</p>
</article>
<article role="tabpanel" id="tab-C" aria-labelledby="tab-3" hidden>
<h3>Tab 3</h3>
<p>Lorem Ipsum Dolor Sit</p>
</article>
</section>
</Draggable>
);
}
};
export default AboutMeModal;
window.addEventListener("DOMContentLoaded", () => {
console.log("event listener added");
const tabs = document.querySelectorAll('[role="tab"]'); //I never get the list of
//tabs back
const tabList = document.querySelector('[role="tablist"]');
// Add a click event handler to each tab
tabs.forEach(tab => {
console.log("here"); //my code never reaches here!
tab.addEventListener("click", changeTabs);
});
});
function changeTabs(e) {
console.log("change tabs");
const target = e.target;
const parent = target.parentNode;
const grandparent = parent.parentNode;
// Remove all current selected tabs
parent
.querySelectorAll('[aria-selected="true"]')
.forEach(t => t.setAttribute("aria-selected", false));
// Set this tab as selected
target.setAttribute("aria-selected", true);
// Hide all tab panels
grandparent
.querySelectorAll('[role="tabpanel"]')
.forEach(p => p.setAttribute("hidden", true));
// Show the selected panel
grandparent.parentNode
.querySelector(`#${target.getAttribute("aria-controls")}`)
.removeAttribute("hidden");
}
DOMContentLoaded
is fired only once when the basic structure of the HTML is known to the browser. It's never called again after the initial load. You shall hook your events directly on the button tabs:
<button id="tab-1" onClick={changeTabs} role="tab" aria-selected="true" aria-controls="tab-A" tabIndex="0">Tab A</button>
<button id="tab-2" onClick={changeTabs} role="tab" aria-selected="false" aria-controls="tab-B" tabIndex="-1">Tab B</button>
<button id="tab-3" onClick={changeTabs} role="tab" aria-selected="false" aria-controls="tab-C" tabIndex="-1">Tab C</button>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With