React. js document.querySelectorAll () ничего не возвращает - PullRequest
5 голосов
/ 18 июня 2020

Я в основном делаю тематическое портфолио windows XP, и я озадачен добавлением вкладок в свои модальные окна. Я следую руководству (https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role), и моя проблема в том, что когда я вызываю document.querySelectorAll ('[role = "tab"]'), я ничего не получаю. Использование querySelector () возвращает null.

Я думал, что, возможно, это потому, что вкладка еще не создана, пока я не открою модальное окно, но даже в этом случае не следует ли прослушиватель событий проверять каждый раз, когда что-то добавляется в DOM? Может быть, область видимости неправильная, но я получаю некоторые ошибки, когда помещаю ее в рендер или где-нибудь в классе.

Вот мой компонент:

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");
}

1 Ответ

1 голос
/ 18 июня 2020

DOMContentLoaded запускается только один раз, когда браузеру известна базовая структура c HTML. После начальной загрузки он больше не вызывается. Вы должны привязать свои события непосредственно к вкладкам кнопок:

<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>
...