Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React.js document.querySelectorAll() not returning anything

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");
}
like image 727
Froshiga Avatar asked Nov 06 '22 06:11

Froshiga


1 Answers

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>
like image 100
px1mp Avatar answered Nov 12 '22 17:11

px1mp