简体   繁体   English

当我在事件处理程序中引用对象的参数时,即使将其设置为对象,该参数也始终为null

[英]When I reference a parameter of an object inside of an event handler, the parameter is always null even when it's set to an object

it's my first Stack Overflow question as I usually find my answers upon googling, so bear with me... 这是我的第一个堆栈溢出问题,因为我通常在谷歌搜索时会找到答案,所以请耐心等待...

I'm working on a project that involves heavy manipulation of canvas elements. 我正在从事一个涉及对画布元素进行大量操作的项目。 To do this, I have imported and used jQuery and jCanvas. 为此,我已经导入并使用了jQuery和jCanvas。 I am also writing the code in ECMAScript 6. For easier logging methods, I'm using loglevel (hence "log.debug" and "log.info" etc., instead of "console.log"). 我也在用ECMAScript 6编写代码。为了简化日志记录方法,我使用了日志级别(因此使用“ log.debug”和“ log.info”等,而不是“ console.log”)。

Currently, my problem is with the event handlers having some weird interactions with an object I use for storing data about each canvas. 当前,我的问题是事件处理程序与我用来存储有关每个画布的数据的对象有一些奇怪的交互。 Basically, in my mousedown and mousemove handlers, I'm using the getCanvasData function to retrieve the data object for that certain canvas, which I apparently successfully retrieve, but when I access the "dragged" parameter, it's always null. 基本上,在我的mousedown和mousemove处理程序中,我使用getCanvasData函数来检索该特定画布的数据对象,显然我已成功检索了该对象,但是当我访问“ draged”参数时,它始终为null。 In other parts of the code, I change that value to an object successfully, but whenever the event handlers access it, it's still null no matter what. 在代码的其他部分,我成功地将该值更改为对象,但是无论何时事件处理程序访问它,该值始终为null。 I have tested whether it really is null by making a getter and setter for the property that prints out its state as it changes (I provided that snippet of code at the end, it's a replacement for the 'data' assignment in getCanvasData function). 我通过为该属性创建一个getter和setter来测试它是否真的为空,该属性会在状态更改时打印出其状态(我在最后提供了该代码段,它代替了getCanvasData函数中的“ data”赋值)。

If you'd like to see the full code in its current form, you can view my project where I'm currently hosting it . 如果您希望以其当前形式查看完整的代码,则可以查看我当前托管它的项目 It's a live version, which means that it's synched with my working environment. 这是一个实时版本,这意味着它与我的工作环境同步。 As I modify something at home, it's going to update the website (so in case you come from the future - it's probably either down or completely different). 当我在家中修改某些内容时,它将更新网站(因此,如果您来自未来,它可能会宕机或完全不同)。

On the website, the move handler is supposed to be responsible for moving one end of a wire/connector when you spawn one (by clicking on one of the inputs or outputs). 在网站上,当您生成电线/连接器的一端(单击输入或输出之一)时,移动处理程序应该负责移动电线/连接器的一端。 Since the handler can't retrieve 'dragged', the wire will never follow the mouse. 由于处理程序无法检索“拖动”,因此导线将永远不会跟随鼠标。 However, when you click on another input/output (keep in mind that inputs only connect to outputs and vice versa) it'll connect the wire between them - that action is performed by accessing the 'dragged' property ('dragged' being a reference to the wire itself) and performing an action on it. 但是,当您单击另一个输入/输出时(请记住,输入仅连接到输出,反之亦然),它将连接它们之间的连线-通过访问“拖动”属性(“拖动”为参考导线本身)并对其执行操作。 Since you can connect the wire, it means 'dragged' is successfully referenced outside of the handler, but not inside of it. 由于您可以连接电线,这意味着在处理程序外部(而不是在处理程序内部)成功引用了“拖动”。

getCanvasData() function: 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;
}

Part of the code I assign the different handlers to all canvases of a certain class: 我将部分代码分配给特定类的所有画布不同的处理程序:

var canvasList = $('.logicExercise'), canvas;

/* some code */

// Initialize each canvas
canvasList.each(function (i, obj) {
    canvas = $(this);
    // Initialize the data stored for the canvas
    getCanvasData(canvas);
    // Draw the UI for the canvas
    drawUI(canvas);
    // Assign mouse handlers (for spawning new wires)
    canvas.mousemove(function(event) {
        mouseMoveHandler(event, canvas);
    });
    canvas.mousedown(function(event) {
        mouseDownHandler(event, canvas);
    });
    // Prevent right-click from firing up the context menu when over the canvas
    canvas.bind('contextmenu', function(e){
        e.preventDefault();
        return false;
    });
});

The mousedown and mousemove handlers: 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;
        }
    }
}

Snippet of code I used to check the state of 'dragged' as it changes: 我用来检查“拖动”状态变化的代码片段:

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;
    }
};

When the above code is in effect, I get a printout informing me that 'dragged' changed to 'Object object', but then when I move the mouse (to trigger mousemove event) I get a printout telling me it's 'null' (not even undefined). 当上面的代码生效时,我得到一个打印输出,通知我“拖放”已更改为“对象对象”,但是当我移动鼠标(触发mousemove事件)时,我得到了一个打印输出,告诉我它是“空”(不是)甚至没有定义)。 When some other part of my project uses it, it uses it successfully and actually retrieves the object. 当我项目的其他部分使用它时,它会成功使用它并实际检索该对象。

You should be using if (canvas[0] === tmp.canvas[0]) to reference the actual canvas objects, and not the jQuery selectors being passed in to getCanvasData() . 您应该使用if (canvas[0] === tmp.canvas[0])引用实际的画布对象,而不是传递给getCanvasData()的jQuery选择器。

When you are checking if (canvas === tmp.canvas) you are checking jQuery selectors, not than the actual canvas object. 当您检查if (canvas === tmp.canvas)您是在检查jQuery选择器, 不是实际的canvas对象。 So, in one place you may be passing $("canvas#foo") and somewhere else you are passing $("canvas .foo") which have different contexts and won't == each other. 因此,在一个地方,您可能传递$("canvas#foo")而在其他地方,您传递的$("canvas .foo")具有不同的上下文,并且不会彼此==。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当作为参数传递时,对象方法回调在事件处理程序中失去其绑定,但在硬编码时不会 - Object-method callback loses its binding in an event handler when passed as a parameter, but not when hard-coded 对象字段为私有时,javascript调用MVC Controller参数始终为null - javascript call MVC Controller parameter always null when object field is private 如何在带有普通 javascript 的 object 中将值设置为参数? - How do I set a value as a parameter inside an object with plain javascript? 尝试获取JSON对象时,jsp中的参数为null - Parameter is null in jsp when trying to get JSON object 如何将对象作为参数传递给 Vue @click 事件处理程序 - How to pass an object as a parameter to Vue @click event handler 在 Javascript 中将对象设置为 null 时是否删除了事件侦听器? - Are event listeners removed when object is set to null in Javascript? JS总是通过mousedown获得相同的事件对象“ e”参数 - JS Always getting the same event object “e” parameter with mousedown 传递给.click()方法参数的参数是否始终是Event对象? - Is the argument passed to .click() method parameter always the Event object? javascript在Object.create的proto参数中使用时,Object vs Object.prototype是什么 - javascript what is Object vs Object.prototype when used in Object.create's proto parameter 当我向其参数列表提供字符串时,JavaScript事件处理程序功能不起作用 - JavaScript event handler function not working when i supply string to its parameter list
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM