点击按钮基于移动元素位置创建元素失败,报style属性读取错误
解决射箭游戏中的两个核心问题:射击功能失效与加速按钮无响应
先来看射击功能(shot函数)的问题,你遇到的控制台报错和新元素位置异常,主要源于这几个错误:
- 错误的元素访问方式:原代码里用
document.arrow是完全错误的——document对象不会自动挂载ID为arrow的元素,直接用你已经声明好的全局变量arrow就可以了。 - 样式获取逻辑错误:初始的
left和top是写在CSS样式表中的,不属于元素的内联样式(inline style),所以直接用arrow.style.left会拿到空字符串,parseInt后变成NaN,导致位置赋值完全失效。你需要用window.getComputedStyle()来获取元素最终渲染的计算样式。 - 新元素缺少定位属性:你创建的新箭头没设置
position属性,left和top样式根本不会生效,必须手动指定position: relative或者absolute。
修复后的shot函数代码:
function shot() { var arrows = document.createElement("div"); document.body.appendChild(arrows); // 设置基础样式,重点补全position属性 arrows.style.backgroundColor = "black"; arrows.style.height = "80px"; arrows.style.width = "1.5px"; arrows.style.position = "relative"; // 获取原箭头的计算后样式 var computedStyle = window.getComputedStyle(arrow); var arrowX = parseInt(computedStyle.left); var arrowY = parseInt(computedStyle.top); // 给新箭头设置与原箭头一致的位置 arrows.style.left = arrowX + "px"; arrows.style.top = arrowY + "px"; }
再解决**faster按钮无法工作的问题**,原因有两个:
- HTML中缺少触发按钮:你的原HTML里只有Shot按钮,没有对应Faster功能的按钮,需要补充:
<button id="fasterBtn" onclick="faster();">Faster!</button>
speed2未随speed更新:你初始化时计算了speed2 = speed/100,但faster函数修改speed后,speed2没有重新计算,导致定时器的延迟时间还是原来的数值,速度自然没变化。
修复后的faster函数:
function faster() { // 防止speed变成负数,加个边界判断 if (speed > 100) { speed -= 100; speed2 = speed / 100; // 同步更新speed2 alert("当前速度:" + speed); } else { alert("已经是最快速度啦!"); } }
额外优化的小细节
- 原HTML里的
<div id="arrow"><div>闭合标签写错了,应该是</div>,这个可能导致DOM结构异常; arrow_move_left函数里不需要重复执行arrow = document.getElementById("arrow");,全局变量已经可用,重复获取没必要。
完整修复后的代码
<!DOCTYPE html> <html> <head> <title>射箭游戏</title> <style> #arrow { background-color: black; height: 80px; width: 1.5px; position: relative; left: 0px; top: 0px; } </style> </head> <body> <div id="arrow"></div> <button id="button" onclick="shot();"> Shot! </button> <button id="fasterBtn" onclick="faster();">Faster!</button> <script> var arrow = document.getElementById("arrow"); var arrowPos = -50; var speed = 1000; var speed2 = speed/100; function arrow_move_right() { arrowPos += 1; arrow.style.left = arrowPos + "px"; if (arrowPos >= 280) { arrow_move_left(); } else { setTimeout(arrow_move_right, speed2); }; }; function arrow_move_left() { arrowPos -= 1; arrow.style.left = arrowPos + "px"; if (arrowPos <= -50) { arrow_move_right(); } setTimeout(arrow_move_left, speed2); }; function faster() { if (speed > 100) { speed -= 100; speed2 = speed / 100; alert("当前速度:" + speed); } else { alert("已经是最快速度啦!"); } } function shot() { var arrows = document.createElement("div"); document.body.appendChild(arrows); arrows.style.backgroundColor = "black"; arrows.style.height = "80px"; arrows.style.width = "1.5px"; arrows.style.position = "relative"; var computedStyle = window.getComputedStyle(arrow); var arrowX = parseInt(computedStyle.left); var arrowY = parseInt(computedStyle.top); arrows.style.left = arrowX + "px"; arrows.style.top = arrowY + "px"; }; // 启动箭头移动 arrow_move_right(); </script> </body> </html>
调整后,射击功能会生成与原箭头同位置的新箭头,加速按钮也能正确改变箭头的移动速度了。
内容的提问来源于stack exchange,提问作者a a
相关产品推荐
相关产品推荐

