Javascript 当我在事件处理程序中引用对象的参数时,该参数始终为null,即使它';设置为一个对象

Javascript 当我在事件处理程序中引用对象的参数时,该参数始终为null,即使它';设置为一个对象,javascript,jquery,ecmascript-6,jcanvas,Javascript,Jquery,Ecmascript 6,Jcanvas,这是我的第一个堆栈溢出问题,因为我通常在谷歌上找到我的答案,所以请容忍我 我正在从事一个涉及画布元素大量操作的项目。为此,我导入并使用了jQuery和jCanvas。我还在ECMAScript 6中编写代码。为了简化日志记录方法,我使用了loglevel(因此使用了“log.debug”和“log.info”等,而不是“console.log”) 目前,我的问题是事件处理程序与用于存储每个画布数据的对象之间存在一些奇怪的交互。基本上,在我的mousedown和mousemove处理程序中,我使用

这是我的第一个堆栈溢出问题,因为我通常在谷歌上找到我的答案,所以请容忍我

我正在从事一个涉及画布元素大量操作的项目。为此,我导入并使用了jQuery和jCanvas。我还在ECMAScript 6中编写代码。为了简化日志记录方法,我使用了loglevel(因此使用了“log.debug”和“log.info”等,而不是“console.log”)

目前,我的问题是事件处理程序与用于存储每个画布数据的对象之间存在一些奇怪的交互。基本上,在我的mousedown和mousemove处理程序中,我使用getCanvasData函数来检索特定画布的数据对象,我显然成功地检索到了该画布,但是当我访问“draugd”参数时,它总是空的。在代码的其他部分中,我成功地将该值更改为对象,但无论事件处理程序何时访问它,它都仍然为null。我已经通过为属性生成一个getter和setter来测试它是否真的为null,该属性在它发生变化时打印出它的状态(我在最后提供了一段代码,它替代了getCanvasData函数中的“data”赋值)

如果您想查看当前形式的完整代码,可以。这是一个实时版本,这意味着它与我的工作环境同步。当我在家里修改一些东西时,它会更新网站(因此,如果你来自未来,它可能会关闭或完全不同)

在网站上,移动处理程序应该负责在生成导线/连接器时移动导线/连接器的一端(通过单击其中一个输入或输出)。由于处理程序无法检索“拖动”,因此导线将永远不会跟随鼠标。但是,当您单击另一个输入/输出时(请记住,输入仅连接到输出,反之亦然),它将连接它们之间的导线-该操作通过访问“拖动”属性(“拖动”是对导线本身的引用)并对其执行操作来执行。由于可以连接导线,这意味着“拖动”在处理程序外部成功引用,而不是在处理程序内部

getCanvasData()函数:

var canvasData = []; // (among other declarations)

function getCanvasData(canvas) {
    var data, i, tmp;
    // Retrieve the stored data
    for (i = 0; i < canvasData.length; i++) {
        tmp = canvasData[i];
        if (canvas === tmp.canvas) {
            // We got the data for our canvas!
            data = tmp;
            // We no longer need to go through the rest of the list, let's break out of the loop
            break;
        }
    }
    // Check if we got anything back
    if (!data) {
        // No data for this canvas is stored yet. We need to initialize it!
        log.info("New canvas data set is being created. Index: " + canvasData.length);
        data = {
            canvas: canvas, // The canvas this data belongs to
            gates: [],      // An array of all the logic gates on the canvas
            wires: [],      // An array of all the wires on the canvas
            spawners: [],   // An array of all the spawners on the canvas
            dragged: null,  // Currently dragged wire which should follow our mouse
            gateWidth: GATE_WIDTH,  // Width of all logic gates on this canvas
            gateHeight: GATE_HEIGHT // Height of all logic gates on this canvas
        };
        // Store the data in our storage.
        canvasData.push(data);
    }
    return data;
}
mousedown和mousemove处理程序:

function mouseMoveHandler(event, canvas) {
    var x = event.pageX - canvas.offset().left,
        y = event.pageY - canvas.offset().top,
        data = getCanvasData(canvas);
    if (data.dragged) {    // <--- ALWAYS NULL, AND THEREFORE FAILS
        if (data.dragged.inputs[0].type) {
            data.dragged.outputs[0].x = x;
            data.dragged.outputs[0].y = y;
            data.dragged.updateCoords();
        } else {
            data.dragged.inputs[0].x = x;
            data.dragged.inputs[0].y = y;
            data.dragged.updateCoords();
        }
    }
}

function mouseDownHandler(event, canvas) {
    var data = getCanvasData(canvas);
    if (event.which === 3) {
        // Right click detected!
        if (data.dragged) {    // <--- ALWAYS NULL, AND THEREFORE FAILS
            // We are dragging something! Right click means we need to remove it.
            data.dragged.remove();
            data.dragged = null;
        }
    }
}

当上面的代码生效时,我得到一个打印输出,通知我“拖动”变为“对象对象”,但当我移动鼠标(触发mousemove事件)时,我得到一个打印输出,告诉我它是“null”(甚至没有定义)。当我的项目的其他部分使用它时,它会成功地使用它并实际检索对象。

您应该使用
if(canvas[0]==tmp.canvas[0])
来引用实际的canvas对象,而不是传递给
getCanvasData()
的jQuery选择器


当您检查
if(canvas===tmp.canvas)
时,您检查的是jQuery选择器,不是实际的canvas对象。因此,在一个地方你可能会传递
$(“canvas#foo”)
,而在另一个地方你会传递
$(“canvas.foo”)
,它们有不同的上下文,不会互相==对方。

如果你在处理
canvasList,你的
canvas
变量不应该是全局变量,确保它总是
null
,在您展示给我们的代码中,没有任何地方可以将
拖动到任何其他内容。@Bergi它不是作用域的顶部,它只是一个函数的摘录。我不能发布所有的代码,代码太多了。@Bergi我把它放在其他地方了。如果我可以发布一个链接,这是我发布这个链接时的实时版本,它链接到我的工作环境,所以我在电脑上所做的任何更改都会上传到那里。如果你真的想看的话,你可以全部看到。不管它是不是全局范围,但它是一个太高的范围<代码>画布
必须进入
每个
回调中。如果(画布[0]==tmp.canvas[0])
成功,则将其更改为
if!
function mouseMoveHandler(event, canvas) {
    var x = event.pageX - canvas.offset().left,
        y = event.pageY - canvas.offset().top,
        data = getCanvasData(canvas);
    if (data.dragged) {    // <--- ALWAYS NULL, AND THEREFORE FAILS
        if (data.dragged.inputs[0].type) {
            data.dragged.outputs[0].x = x;
            data.dragged.outputs[0].y = y;
            data.dragged.updateCoords();
        } else {
            data.dragged.inputs[0].x = x;
            data.dragged.inputs[0].y = y;
            data.dragged.updateCoords();
        }
    }
}

function mouseDownHandler(event, canvas) {
    var data = getCanvasData(canvas);
    if (event.which === 3) {
        // Right click detected!
        if (data.dragged) {    // <--- ALWAYS NULL, AND THEREFORE FAILS
            // We are dragging something! Right click means we need to remove it.
            data.dragged.remove();
            data.dragged = null;
        }
    }
}
data = {
    canvas: canvas, // The canvas this data belongs to
    gates: [],      // An array of all the logic gates on the canvas
    wires: [],      // An array of all the wires on the canvas
    spawners: [],   // An array of all the spawners on the canvas
    gateWidth: GATE_WIDTH,  // Width of all logic gates on this canvas
    gateHeight: GATE_HEIGHT,// Height of all logic gates on this canvas
    _dragged: null,
    set dragged(obj) {
        log.info("'dragged' is changing to '" + obj + "'.");
        this._dragged = obj;
    },
    get dragged() {
        log.info("'dragged' is being retrieved when it's '" + this._dragged + "'.");
        return this._dragged;
    }
};