PHPRad项目中Canvas背景图不显示及按钮误提交表单问题求助
PHPRad中Canvas使用问题的解决方案
问题说明
- 自定义视图添加的Script未生效,Canvas背景的线上图片完全不显示
- 点击「Free Drawing」和「Remove」按钮时,即使添加了
event.preventDefault(),仍会自动提交表单
原代码参考
JS代码
alert('testing if the script is well connected') const canvas = document.getElementById(\"corolla-canvas\"); const ctx = canvas.getContext(\"2d\"); const img = new Image(); img.src = \"https://i.ibb.co/QF5k508/Removal-69.png\"; img.onload = function () { ctx.drawImage(img, 0, 0, canvas.width, canvas.height); }; let isDrawing = false; let isErasing = false; const drawButton = document.getElementById(\"corollax-draw\"); const removeButton = document.getElementById(\"corollax-remove\"); drawButton.addEventListener(\"click\", function () { removeButton.disabled = false; ctx.drawImage(img, 0, 0, canvas.width, canvas.height); canvas.addEventListener(\"mousedown\", startDrawing); canvas.addEventListener(\"mousemove\", draw); canvas.addEventListener(\"mouseup\", endDrawing); }); removeButton.addEventListener(\"click\", function () { drawButton.disabled = false; ctx.globalCompositeOperation = \"destination-out\"; canvas.addEventListener(\"mousedown\", startErasing); canvas.addEventListener(\"mousemove\", erase); canvas.addEventListener(\"mouseup\", endErasing); }); function startDrawing(e) { isDrawing = true; ctx.beginPath(); ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop); } function draw(e) { if (isDrawing) { ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop); ctx.stroke(); } } function endDrawing(e) { isDrawing = false; } function startErasing(e) { isErasing = true; ctx.beginPath(); ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop); } function erase(e) { if (isErasing) { ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop); ctx.stroke(); } } function endErasing(e) { isErasing = false; ctx.globalCompositeOperation = \"source-over\"; } drawButton.addEventListener(\"click\", function (event) { event.preventDefault(); removeButton.disabled = false; ctx.drawImage(img, 0, 0, canvas.width, canvas.height); canvas.addEventListener(\"mousedown\", startDrawing); canvas.addEventListener(\"mousemove\", draw); canvas.addEventListener(\"mouseup\", endDrawing); }); removeButton.addEventListener(\"click\", function (event) { event.preventDefault(); drawButton.disabled = false; ctx.globalCompositeOperation = \"destination-out\"; canvas.addEventListener(\"mousedown\", startErasing); canvas.addEventListener(\"mousemove\", erase); canvas.addEventListener(\"mouseup\", endErasing); });
HTML代码
<div class=\"canvases\"> <!-- Corolla Canvas --> <div class=\"corolla-canvas\"> <input type=\"hidden\" name=\"corolla_data\" value=\"\" /> <div class=\"buttons-container\"> <button id=\"corollax-draw\" class=\"form-button\"> Free Drawing </button> <button id=\"corollax-remove\" disabled=\"disabled\">Remove</button> </div> <canvas id=\"corolla-canvas\" width=\"650px\" height=\"330px\" name=\"corolla_data\" ></canvas> </div> </canvas> </div>
分步解决方案
1. 解决Canvas图片不显示 & Script未生效问题
- DOM加载时机修正:JS代码要等DOM完全加载后再执行,否则可能找不到Canvas元素。用
DOMContentLoaded事件包裹所有JS逻辑。 - Canvas属性修正:Canvas的
width和height属性不需要加px单位,直接写数值即可,否则会导致绘制尺寸异常。 - 图片加载优化:添加
img.crossOrigin = "anonymous"确保跨域图片能正常加载,同时增加onerror事件排查加载失败原因。 - 移除重复事件绑定:原代码给按钮重复绑定了两次click事件,导致逻辑冲突,合并成一次绑定即可。
2. 解决按钮自动提交表单问题
- 设置按钮类型:HTML中button默认类型是
submit,在表单内点击会触发提交。给按钮加上type="button",从根源避免默认提交行为。 - 确保
preventDefault()生效:合并重复的事件绑定后,event.preventDefault()会在唯一的click事件处理中执行,避免因重复绑定导致的失效。
修正后的完整代码
HTML代码
<div class="canvases"> <!-- Corolla Canvas --> <div class="corolla-canvas"> <input type="hidden" name="corolla_data" value="" /> <div class="buttons-container"> <!-- 添加type="button"防止默认提交 --> <button id="corollax-draw" class="form-button" type="button"> Free Drawing </button> <button id="corollax-remove" disabled="disabled" type="button">Remove</button> </div> <!-- 移除width/height的px单位 --> <canvas id="corolla-canvas" width="650" height="330" name="corolla_data" ></canvas> </div> </div> <!-- 移除原HTML中多余的闭合标签 -->
JS代码
// 等待DOM加载完成后执行脚本 document.addEventListener('DOMContentLoaded', function() { alert('testing if the script is well connected'); const canvas = document.getElementById("corolla-canvas"); if (!canvas) { console.error('Canvas元素未找到'); return; } const ctx = canvas.getContext("2d"); const img = new Image(); // 允许跨域加载图片 img.crossOrigin = "anonymous"; img.src = "https://i.ibb.co/QF5k508/Removal-69.png"; img.onload = function () { console.log('图片加载成功'); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); }; img.onerror = function() { console.error('图片加载失败,请检查地址或跨域设置'); }; let isDrawing = false; let isErasing = false; const drawButton = document.getElementById("corollax-draw"); const removeButton = document.getElementById("corollax-remove"); // 绘制按钮点击逻辑(只绑定一次) drawButton.addEventListener("click", function (event) { event.preventDefault(); removeButton.disabled = false; // 图片加载完成后再重绘背景 if (img.complete) { ctx.drawImage(img, 0, 0, canvas.width, canvas.height); } // 移除擦除相关事件,避免冲突 canvas.removeEventListener("mousedown", startErasing); canvas.removeEventListener("mousemove", erase); canvas.removeEventListener("mouseup", endErasing); // 添加绘制事件监听 canvas.addEventListener("mousedown", startDrawing); canvas.addEventListener("mousemove", draw); canvas.addEventListener("mouseup", endDrawing); }); // 擦除按钮点击逻辑(只绑定一次) removeButton.addEventListener("click", function (event) { event.preventDefault(); drawButton.disabled = false; ctx.globalCompositeOperation = "destination-out"; // 移除绘制相关事件,避免冲突 canvas.removeEventListener("mousedown", startDrawing); canvas.removeEventListener("mousemove", draw); canvas.removeEventListener("mouseup", endDrawing); // 添加擦除事件监听 canvas.addEventListener("mousedown", startErasing); canvas.addEventListener("mousemove", erase); canvas.addEventListener("mouseup", endErasing); }); // 绘制相关函数 function startDrawing(e) { isDrawing = true; ctx.beginPath(); ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop); } function draw(e) { if (isDrawing) { ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop); ctx.stroke(); } } function endDrawing(e) { isDrawing = false; } // 擦除相关函数 function startErasing(e) { isErasing = true; ctx.beginPath(); ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop); } function erase(e) { if (isErasing) { ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop); ctx.stroke(); } } function endErasing(e) { isErasing = false; ctx.globalCompositeOperation = "source-over"; } });
内容的提问来源于stack exchange,提问作者Tshepo Moeletsi
相关产品推荐
相关产品推荐

