SVG井字棋游戏onClick事件随机失效问题求助
井字棋点击事件随机失效的问题修复
你的井字棋点击事件看似随机失效,其实是三个明确的代码问题导致的,逐个给你理清楚:
1. 回合判断的赋值错误
你在判断当前回合时写了if (whosTurn = "x"),这是赋值操作而非比较判断,每次执行到这里都会强制把whosTurn设为"x",直接打乱了回合切换的逻辑,导致点击后的行为完全不可预测。
要改成比较判断:if (whosTurn === "x")(严格相等推荐)或者if (whosTurn == "x")。
2. 冗余的无效代码
代码里存在eleXstyle == "black"这类语句,只是做了一次值比较,没有任何实际作用(既没赋值也没影响逻辑),完全可以删掉,避免干扰代码逻辑。
3. SVG元素层级导致的点击拦截
SVG元素是按定义顺序渲染的,后定义的元素会覆盖在先定义的元素上方。你的rect是最先定义的,后面的line和circle都在rect上层,哪怕这些元素是透明的,点击时也会被它们拦截(但这些元素没绑定点击事件),导致rect的onclick无法触发。
解决办法是给所有rect加上style="pointer-events: all;",让它们无视层级拦截,直接响应点击。
修复后的完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tic Tac Toe</title> <script> let whosTurn = "o"; function clickedSquare(x1,x2, o) { console.log('hi!') var eleX = document.getElementById(x1); var eleXR = document.getElementById(x2) var eleO = document.getElementById(o); var eleXstyle = eleX.getAttribute("stroke"); var eleOstyle = eleO.getAttribute("stroke"); if (eleXstyle === "transparent" && eleOstyle === "transparent") { // 修复:改成比较判断 if (whosTurn === "x") { eleX.setAttribute( "stroke", "black"); eleXR.setAttribute( "stroke", "black"); whosTurn = "o" } else { eleO.setAttribute( "stroke", "black"); whosTurn = "x" } } console.log(whosTurn) } function checkForWinner() { // 后续可补充获胜判断逻辑 } </script> </head> <body> <svg width="500" height="500" style="background-color: black;" viewBox="0 0 500 500"> <!-- 修复:给每个rect添加pointer-events: all --> <rect width="160" height="160" x="0" y="0" fill="red" style="pointer-events: all;" onclick="clickedSquare('x1l','x1r','circle1');"></rect> <rect width="160" height="160" x="170" y="0" fill="white" style="pointer-events: all;" onclick="clickedSquare('x2l','x2r','circle2'); checkForWinner();"></rect> <rect width="160" height="160" x="340" y="0" fill="white" style="pointer-events: all;" onclick="clickedSquare('x3l','x3r','circle3'); checkForWinner();"></rect> <rect width="160" height="160" x="0" y="170" fill="white" style="pointer-events: all;" onclick="clickedSquare('x4l','x4r','circle4'); checkForWinner();"></rect> <rect width="160" height="160" x="170" y="170" fill="white" style="pointer-events: all;" onclick="clickedSquare('x5l','x5r','circle5'); checkForWinner();"></rect> <rect width="160" height="160" x="340" y="170" fill="white" style="pointer-events: all;" onclick="clickedSquare('x6l','x6r','circle6'); checkForWinner();"></rect> <rect width="160" height="160" x="0" y="340" fill="white" style="pointer-events: all;" onclick="clickedSquare('x7l','x7r','circle7'); checkForWinner();"></rect> <rect width="160" height="160" x="170" y="340" fill="white" style="pointer-events: all;" onclick="clickedSquare('x8l','x8r','circle8'); checkForWinner();"></rect> <rect width="160" height="160" x="340" y="340" fill="white" style="pointer-events: all;" onclick="clickedSquare('x9l','x9r','circle9'); checkForWinner();"></rect> <line x1="20" y1="20" x2="130" y2="120" stroke="transparent" stroke-width="5px" class="exes x1" id="x1l"></line> <line x1="130" y1="20" x2="20" y2="120" stroke="transparent" stroke-width="5px" class="exes x1" id="x1r"></line> <line x1="190" y1="20" x2="300" y2="120" stroke="transparent" stroke-width="5px" class="exes x2" id="x2l"></line> <line x1="300" y1="20" x2="190" y2="120" stroke="transparent" stroke-width="5px" class="exes x2" id="x2r"></line> <line x1="360" y1="20" x2="470" y2="120" stroke="transparent" stroke-width="5px" class="exes x3" id="x3l"></line> <line x1="470" y1="20" x2="360" y2="120" stroke="transparent" stroke-width="5px" class="exes x3" id="x3r"></line> <line x1="20" y1="190" x2="130" y2="290" stroke="transparent" stroke-width="5px" class="exes x4" id="x4l"></line> <line x1="130" y1="190" x2="20" y2="290" stroke="transparent" stroke-width="5px" class="exes x4" id="x4r"></line> <line x1="190" y1="190" x2="300" y2="290" stroke="transparent" stroke-width="5px" class="exes x5" id="x5l"></line> <line x1="300" y1="190" x2="190" y2="290" stroke="transparent" stroke-width="5px" class="exes x5" id="x5r"></line> <line x1="360" y1="190" x2="470" y2="290" stroke="transparent" stroke-width="5px" class="exes x6" id="x6l"></line> <line x1="470" y1="190" x2="360" y2="290" stroke="transparent" stroke-width="5px" class="exes x6" id="x6r"></line> <line x1="20" y1="360" x2="130" y2="470" stroke="transparent" stroke-width="5px" class="exes x7" id="x7l"></line> <line x1="130" y1="360" x2="20" y2="470" stroke="transparent" stroke-width="5px" class="exes x7" id="x7r"></line> <line x1="190" y1="360" x2="300" y2="470" stroke="transparent" stroke-width="5px" class="exes x8" id="x8l"></line> <line x1="300" y1="360" x2="190" y2="470" stroke="transparent" stroke-width="5px" class="exes x8" id="x8r"></line> <line x1="360" y1="360" x2="470" y2="470" stroke="transparent" stroke-width="5px" class="exes x9" id="x9l"></line> <line x1="470" y1="360" x2="360" y2="470" stroke="transparent" stroke-width="5px" class="exes x9" id="x9r"></line> <circle cx="70" cy="70" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle1"></circle> <circle cx="250" cy="70" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle2"></circle> <circle cx="430" cy="70" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle3"></circle> <circle cx="70" cy="250" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle4"></circle> <circle cx="250" cy="250" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle5"></circle> <circle cx="430" cy="250" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle6"></circle> <circle cx="70" cy="430" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle7"></circle> <circle cx="250" cy="430" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle8"></circle> <circle cx="430" cy="430" r="60" stroke="transparent" stroke-width="5px" fill="transparent" class="circle" id="circle9"></circle> </svg> </body> </html>
内容的提问来源于stack exchange,提问作者Maddy Young
相关产品推荐
相关产品推荐

