使用事件引用删除事件侦听器

时间:2021-04-25 17:45:35

标签: javascript reactjs events event-listener

我正在尝试让网页在 Q、W、E、R 和 T 按键上播放鼓声音频。音频存储在 React 状态对象中:

    const [sounds, setSounds] = useState({
        loadState: false,
        Q : "",
        W : "",
        E : "", 
        R : "",
        T : ""
    })

并且将被更新为几个常量之一,代表稍后显示的按钮控制的不同样式:

    function makeAudioObj(genre) {
        return ({
            loadState: true,
            Q : new Audio(`/audio/${genre}/${genre}_kick.wav`),
            W : new Audio(`/audio/${genre}/${genre}_snare.wav`),
            E : new Audio(`/audio/${genre}/${genre}_hat.wav`), 
            R : new Audio(`/audio/${genre}/${genre}_cymbal.wav`),
            T : new Audio(`/audio/${genre}/${genre}_misc.wav`)
        })
    }

    const rnbAudio = makeAudioObj('rnb');
    const hiphopAudio = makeAudioObj('hiphop');
    const jazzAudio = makeAudioObj('jazz');
    const electronicAudio = makeAudioObj('electronic');

按键功能添加为:

    function pressKey(e) {
        let key = e.key.toUpperCase();
        if (sounds.loadState) {
            sounds[key].play();
        }
    }

    function setListener() {
        document.addEventListener('keypress', pressKey);
    }

    function resetListener() {
        document.removeEventListener('keypress', pressKey);
    }

最后,这被打包成一个由处理样式更改的按钮执行的函数:

    const [firstLoad, setFirstLoad] = useState(false) // necessary to prevent removal of EventListener before it exists
    function kitSelection(genre, event) {
        if (firstLoad) {
            resetListener();
        }
        setSounds(genre);
        setListener();
        if (!firstLoad) {
            setFirstLoad(true);
        }
    }

    return (
        <div>
            <button onClick={e => kitSelection(rnbAudio, e)}>{'R&B'}</button>
            <button onClick={e => kitSelection(hiphopAudio, e)}>Hip-Hop</button>
            <button onClick={e => kitSelection(jazzAudio, e)}>Jazz</button>
            <button onClick={e => kitSelection(electronicAudio, e)}>Electronic</button>
        </div>
)

问题是 removeEventListener 不起作用,但与我发现的本网站上的其他帖子不一致。我认为这个问题与 pressKey 引用一个事件有关,这意味着它试图删除一个与设置不同的函数。但是,尽管以相同的方式引用 pressKey,但将这些相同的 setListener/resetListener 函数放入页面其他位置的按钮表单中(例如,处理添加和删除 EventListener 的按钮)确实有效。这让我对我实施这个错误的方式感到困惑。此外,如果这确实是问题所在,我不知道如何在不引用事件的情况下实现像我所追求的功能。

0 个答案:

没有答案