单击一次时阻止 span 元素上的 onClick 事件
Prevent an onClick event on a span element when it was clicked once
我正在构建一个游戏,您必须根据答案是正确还是错误来单击交叉象形图或检查象形图。但是一旦你回答了你就不能再点击两个象形图的none(即使你没有点击的那个)。
为此,我在包含象形图的元素上使用了 useRef,并尝试禁用该元素。它没有用。
我也试过让他们的父元素“uneventable”,但它也没有用
如有任何帮助,我将不胜感激。谢谢
const pictoAnswer = useRef()
const divParent = useRef()
pictoAnswer.current.disabled = true
divParent.current.pointerEvents = "none"
总览
import React, { useState, useRef } from "react";
// modules
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck, faTimes } from "@fortawesome/free-solid-svg-icons";
const WordList = () => {
const liBgColor = useRef();
const pictoAnswer = useRef();
const divParent = useRef();
// change the color bg of the list element
const isCorrect = (answer) => {
if (answer) {
liBgColor.current.style.backgroundColor = "#5DCF36";
} else {
liBgColor.current.style.backgroundColor = "#d15f5f";
}
};
//list of word to make guess
let wordsToGuess = ["chambre", "salon", "rire", "fusée"];
const numberOfWordToGuess = wordsToGuess.length;
const [indexWord, setIndexWord] = useState(1);
console.log("indexWord:", indexWord);
const [wordToDisplay, setWordToDisplay] = useState([wordsToGuess[0]]);
// push the next word to guess into the wordToDisplay array
const handleAnswer = (answer) => {
pictoAnswer.current.disabled = true;
divParent.current.pointerEvents = "none";
//set the new index of the word item
setIndexWord(indexWord + 1);
//change the bgColor depending on the answer
isCorrect(answer);
//would display the next word or not
if (indexWord == numberOfWordToGuess || indexWord > numberOfWordToGuess) {
console.log("no more word to guess");
} else {
setWordToDisplay([...wordToDisplay, wordsToGuess[indexWord]]);
}
};
return (
<ul className="word__list">
{wordToDisplay.map((word, i) => (
<li key={i} className="word__item" ref={liBgColor}>
<p className="word">{word}</p>
<div className="icon-box" ref={divParent}>
<span
ref={pictoAnswer}
onClick={() => {
handleAnswer(false);
}}
>
<FontAwesomeIcon icon={faTimes} color={"#FF5252"} />
</span>
<span
ref={pictoAnswer}
onClick={() => {
handleAnswer(true);
}}
>
<FontAwesomeIcon icon={faCheck} color={"#008000"} />
</span>
</div>
</li>
))}
</ul>
);
};
export default WordList;
您的代码的主要问题是不正确地使用 React 引用来操作 DOM 个元素。
解决方案
- 存储初始化为空值的“已解决”状态数组,以指示单词是否已被标记true/false。相同的条件用于防止进一步的“点击”处理。
- 使用 CSS 设置列表项的样式。
- 更新
handleAnswer
以设置“已解决”状态并增加单词索引。
- 使用
useEffect
挂钩更新要显示的字词。
代码:
const wordsToGuess = ["chambre", "salon", "rire", "fusée"];
const App = () => {
const [indexWord, setIndexWord] = useState(0);
const [wordToDisplay, setWordToDisplay] = useState([]);
const [settled, setSettled] = useState(Array(wordsToGuess.length).fill(null));
useEffect(() => {
setWordToDisplay(wordsToGuess.slice(0, indexWord + 1));
}, [indexWord]);
const handleAnswer = (index, answer) => () => {
if (settled[index] === null) {
setSettled((settled) =>
settled.map((el, i) => (i === indexWord ? answer : el))
);
if (indexWord < wordsToGuess.length - 1) setIndexWord((i) => i + 1);
}
};
return (
<ul className="word__list">
{wordToDisplay.map((word, i) => (
<li
key={i}
className={classNames("word__item", {
"settled-true": settled[i] === true,
"settled-false": settled[i] === false
})}
>
<p className="word">{word}</p>
<div className="icon-box">
<span onClick={handleAnswer(i, false)}>
<FontAwesomeIcon icon={faTimes} color={"#FF5252"} />
</span>
<span onClick={handleAnswer(i, true)}>
<FontAwesomeIcon icon={faCheck} color={"#008000"} />
</span>
</div>
</li>
))}
</ul>
);
};
CSS:
.settled-true {
background-color: #5dcf36;
}
.settled-false {
background-color: #d15f5f;
}
演示
我正在构建一个游戏,您必须根据答案是正确还是错误来单击交叉象形图或检查象形图。但是一旦你回答了你就不能再点击两个象形图的none(即使你没有点击的那个)。
为此,我在包含象形图的元素上使用了 useRef,并尝试禁用该元素。它没有用。 我也试过让他们的父元素“uneventable”,但它也没有用
如有任何帮助,我将不胜感激。谢谢
const pictoAnswer = useRef()
const divParent = useRef()
pictoAnswer.current.disabled = true
divParent.current.pointerEvents = "none"
总览
import React, { useState, useRef } from "react";
// modules
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck, faTimes } from "@fortawesome/free-solid-svg-icons";
const WordList = () => {
const liBgColor = useRef();
const pictoAnswer = useRef();
const divParent = useRef();
// change the color bg of the list element
const isCorrect = (answer) => {
if (answer) {
liBgColor.current.style.backgroundColor = "#5DCF36";
} else {
liBgColor.current.style.backgroundColor = "#d15f5f";
}
};
//list of word to make guess
let wordsToGuess = ["chambre", "salon", "rire", "fusée"];
const numberOfWordToGuess = wordsToGuess.length;
const [indexWord, setIndexWord] = useState(1);
console.log("indexWord:", indexWord);
const [wordToDisplay, setWordToDisplay] = useState([wordsToGuess[0]]);
// push the next word to guess into the wordToDisplay array
const handleAnswer = (answer) => {
pictoAnswer.current.disabled = true;
divParent.current.pointerEvents = "none";
//set the new index of the word item
setIndexWord(indexWord + 1);
//change the bgColor depending on the answer
isCorrect(answer);
//would display the next word or not
if (indexWord == numberOfWordToGuess || indexWord > numberOfWordToGuess) {
console.log("no more word to guess");
} else {
setWordToDisplay([...wordToDisplay, wordsToGuess[indexWord]]);
}
};
return (
<ul className="word__list">
{wordToDisplay.map((word, i) => (
<li key={i} className="word__item" ref={liBgColor}>
<p className="word">{word}</p>
<div className="icon-box" ref={divParent}>
<span
ref={pictoAnswer}
onClick={() => {
handleAnswer(false);
}}
>
<FontAwesomeIcon icon={faTimes} color={"#FF5252"} />
</span>
<span
ref={pictoAnswer}
onClick={() => {
handleAnswer(true);
}}
>
<FontAwesomeIcon icon={faCheck} color={"#008000"} />
</span>
</div>
</li>
))}
</ul>
);
};
export default WordList;
您的代码的主要问题是不正确地使用 React 引用来操作 DOM 个元素。
解决方案
- 存储初始化为空值的“已解决”状态数组,以指示单词是否已被标记true/false。相同的条件用于防止进一步的“点击”处理。
- 使用 CSS 设置列表项的样式。
- 更新
handleAnswer
以设置“已解决”状态并增加单词索引。 - 使用
useEffect
挂钩更新要显示的字词。
代码:
const wordsToGuess = ["chambre", "salon", "rire", "fusée"];
const App = () => {
const [indexWord, setIndexWord] = useState(0);
const [wordToDisplay, setWordToDisplay] = useState([]);
const [settled, setSettled] = useState(Array(wordsToGuess.length).fill(null));
useEffect(() => {
setWordToDisplay(wordsToGuess.slice(0, indexWord + 1));
}, [indexWord]);
const handleAnswer = (index, answer) => () => {
if (settled[index] === null) {
setSettled((settled) =>
settled.map((el, i) => (i === indexWord ? answer : el))
);
if (indexWord < wordsToGuess.length - 1) setIndexWord((i) => i + 1);
}
};
return (
<ul className="word__list">
{wordToDisplay.map((word, i) => (
<li
key={i}
className={classNames("word__item", {
"settled-true": settled[i] === true,
"settled-false": settled[i] === false
})}
>
<p className="word">{word}</p>
<div className="icon-box">
<span onClick={handleAnswer(i, false)}>
<FontAwesomeIcon icon={faTimes} color={"#FF5252"} />
</span>
<span onClick={handleAnswer(i, true)}>
<FontAwesomeIcon icon={faCheck} color={"#008000"} />
</span>
</div>
</li>
))}
</ul>
);
};
CSS:
.settled-true {
background-color: #5dcf36;
}
.settled-false {
background-color: #d15f5f;
}