You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS使用setInterval无输出,且收到非被动事件监听器违规提示

问题修复方案

线条无法显示问题修复

你对setInterval的传参逻辑有误:setInterval第一个参数要求传入待执行的函数引用,但你写的drawing.output(Canvas.ctx)是直接调用了output方法,将它的返回值(undefined)传给了setInterval,因此该方法只会在初始化时执行一次,不会按500ms的间隔定时重绘。
修复方式为传入箭头函数包裹执行逻辑:

// 修复前
window.setInterval(drawing.output(Canvas.ctx), 500);
// 修复后
window.setInterval(() => drawing.output(Canvas.ctx), 500);

另外补充优化点:

  • 你当前只监听了mousedown、touchstart事件,只会在鼠标按下/触摸开始时记录一次坐标,要绘制连续线条需要额外监听mousemove/touchmove/mouseup/touchend事件,在指针移动过程中持续记录坐标
  • 原代码中将Drawing.prototype.output的定义放在了构造函数内部,每次实例化Drawing时都会重复覆盖原型方法,属于冗余写法,建议移到构造函数外部
  • 触摸事件的坐标需要从evt.changedTouches[0]中获取,否则移动端触摸绘制会失效

「Violation: Added non-passive event listener」警告修复

这个警告是浏览器针对触摸类事件的性能优化提示:对于touchstart、touchmove这类可能阻塞页面滚动的事件,如果你不会在监听器中调用evt.preventDefault(),需要显式将passive属性设为true,告诉浏览器可以直接执行滚动无需等待事件监听器执行完成。
将原来的触摸事件监听的第三个参数从布尔值改为配置对象即可:

// 修复前
Canvas.canvas.addEventListener("touchstart", catchAction, false);
// 修复后
Canvas.canvas.addEventListener("touchstart", catchAction, {passive: true});

完整修复后代码

var Canvas = {
    canvas : undefined,
    ctx : undefined
};
var Mouse = {
    x : [0],
    y : [0],
    isDrawing: false // 新增绘制状态判断,避免未按下时也记录坐标
};
function Drawing(width, colour){
    this.width = width;
    this.colour = colour;
}
// 原型方法移到构造函数外,避免重复赋值
Drawing.prototype.output = function(ctx){
    ctx.strokeStyle = this.colour;
    ctx.lineWidth = this.width;
    ctx.lineCap = 'round'; // 可选优化:让线条端点更圆润
    for (var i = 0; i < Mouse.x.length-1; i++) {
        ctx.beginPath();
        ctx.moveTo(Mouse.x[i], Mouse.y[i]);
        ctx.lineTo(Mouse.x[i+1], Mouse.y[i+1]);
        ctx.stroke();
    }
}
Canvas.start = function () {
    function catchAction(evt) {
        // 兼容鼠标和触摸事件的坐标获取
        const pageX = evt.changedTouches ? evt.changedTouches[0].pageX : evt.pageX;
        const pageY = evt.changedTouches ? evt.changedTouches[0].pageY : evt.pageY;
        // 按下/触摸开始时启动绘制
        if(evt.type === 'mousedown' || evt.type === 'touchstart') {
            Mouse.isDrawing = true;
            Mouse.x.push(pageX);
            Mouse.y.push(pageY);
            return;
        }
        // 抬起/触摸结束时停止绘制
        if(evt.type === 'mouseup' || evt.type === 'touchend') {
            Mouse.isDrawing = false;
            return;
        }
        // 移动过程中仅在绘制状态下记录坐标
        if(Mouse.isDrawing) {
            Mouse.x.push(pageX);
            Mouse.y.push(pageY);
        }
    }
    Canvas.canvas = document.getElementById("myCanvas");
    Canvas.canvas.width = Canvas.canvas.height = 600;
    Canvas.ctx = Canvas.canvas.getContext('2d');
    let drawing = new Drawing(10, 'red');
    // 补全全流程事件监听
    Canvas.canvas.addEventListener("mousedown", catchAction, false);
    Canvas.canvas.addEventListener("mousemove", catchAction, false);
    Canvas.canvas.addEventListener("mouseup", catchAction, false);
    Canvas.canvas.addEventListener("touchstart", catchAction, {passive: true});
    Canvas.canvas.addEventListener("touchmove", catchAction, {passive: true});
    Canvas.canvas.addEventListener("touchend", catchAction, {passive: true});
    // 修复setInterval传参
    window.setInterval(() => drawing.output(Canvas.ctx), 500);
};
document.addEventListener( 'DOMContentLoaded', Canvas.start);

内容的提问来源于stack exchange,提问作者Nic Oatridge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 05:36:03