JS问题。为啥onclick事件单击一次后,在页面无刷新的情况下,单击第二次无效?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS问题。为啥onclick事件单击一次后,在页面无刷新的情况下,单击第二次无效?相关的知识,希望对你有一定的参考价值。
JS问题。为什么onclick事件单击一次后,在页面无刷新的情况下,单击第二次无效?如何能重复onclick。并且能让function重复执行?
参考技术A onclick 注册了就会一直有效,你说那种单击一次就失效情况,反而要用专门写个释放动作才会出现。估计,单击一次后代码出错。后面单击就无效了 参考技术B 这是一个死判断嘛,相当于你自己把按钮禁用了。 参考技术C 你是要点一次就反复执行一个函数?试试setTimeout("function",time); 参考技术D 根据你描述,是你代码写的有问题,上代码 第5个回答 2013-10-11 把代码贴上来吧,这样好针对问题讲啊阻止单击一次 span 元素上的 onClick 事件
【中文标题】阻止单击一次 span 元素上的 onClick 事件【英文标题】:Prevent an onClick event on a span element when it was clicked once 【发布时间】:2021-02-24 19:26:17 【问题描述】:我正在构建一个游戏,您必须在其中单击十字象形图或检查象形图,具体取决于答案是正确还是错误。但是一旦你回答了你就不能再点击这两个象形图中的任何一个(即使是你没有点击的那个)。
为了做到这一点,我在包含象形图的元素上使用了 useRef,并尝试禁用该元素。它没有用。 我也试图让他们的父元素“不可改变”,但它也没有工作
我将不胜感激。谢谢
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;
codeSandBox
【问题讨论】:
document.querySelector("span").addEventListener("click", function(e) e.preventDefault(); return false; , once : true); 没有足够的信息可以确定,但是您至少应该检查带有图片的组件没有被卸载和重新安装,因为这将重置其禁用/启用状态。 不应该阻止进一步的点击注册,如果它被回答,你不应该传递任何 onClick 处理程序,所以点击不会做任何事情。或者,您可以检查处理程序中的已回答状态,如果为真,则退出任何进一步的操作。 你为什么不使用语义按钮(带有disabled
属性)?您的 React ref 用法似乎不正确,因为只有最后一个映射的 word
元素附加了 ref,您甚至在同一渲染中分配了两次 pictoAnswer
ref(!!)。 indexWord
不会是 handleAnswer
中的增量值,但也许这没问题 (???) 虽然我怀疑不是因为您稍后尝试推送一个新单词以显示 @987654329 @。当您应该使用 className
或 style
设置任何样式(而不是 DOM 操作)时,似乎误用了 React refs。
您能否为此代码创建一个 running 代码框,以便我们更好地了解您要完成的工作?
【参考方案1】:
您的代码的主要问题是不正确地使用 React refs 来操作 DOM 元素。
解决方案
-
存储一个初始化为空值的“已解决”状态数组,以指示单词是否已被标记为真/假。相同的条件用于防止进一步的“点击”处理。
使用 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;
演示
【讨论】:
以上是关于JS问题。为啥onclick事件单击一次后,在页面无刷新的情况下,单击第二次无效?的主要内容,如果未能解决你的问题,请参考以下文章
如何让一个按钮自动触发,自动执行onclick鼠标单击事件. 默认已点击.