JavaScript 对象:“addEventListener 不是函数”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30946303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:58:11  来源:igfitidea点击:

JavaScript objects: 'addEventListener is not a function'

javascripthtmlobjectcanvasmapping

提问by kformeck

I create an array of JavaScript objects called elements and loop through it in order to draw every one on a canvas as well as hooking up a few event handlers to it. However, I get an error stating that

我创建了一个称为元素的 JavaScript 对象数组并遍历它,以便在画布上绘制每个对象,并将一些事件处理程序连接到它。但是,我收到一个错误说明

'Uncaught TypeError: elements[i].addEventListener is not a function'

Here is the code:

这是代码:

$(document).ready(onDocumentReady);
function onDocumentReady() {
    var COLOR_NORMAL = '#005A84';
    var COLOR_SELECTED = '#00F2F2';
    var COLOR_MOUSEOVER = '#5BA621';

    var canvas = document.getElementById("mapCanvas");
    var context = canvas.getContext('2d');
    var data = @Html.Raw(Json.Encode(Model.DiePrintList));
    var elem =
        canvas,
        left = elem.offsetLeft,
        top = elem.offsetTop,
        context = elem.getContext('2d'),
        elements = [];
    for (var i = 0; i < data.length; i++) {
        elements.push({
            color: '#0489B1',
            width: 15,
            height: 15,
            row: data[i].Row,
            col: data[i].Col,
            top: data[i].Row * 20,
            left: data[i].Col * 20
        });
    }
    for (var i = 0; i < elements.length; i++) {
        elements[i].addEventListener('click', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_SELECTED;
            drawElement(context, hitElement);
        }, false);
        elements[i].addEventListener('mouseover', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_MOUSEOVER;
            drawElement(context, hitElement);
        }, false);
        elements[i].addEventListener('mouseout', function(event) {
            var hitElement = getHitElement(elements, event.pageX - left, event.pageY - top);
            hitElement.color = COLOR_SELECTED;
            drawElement(context, hitElement);
        }, false);
        drawElement(context, elements[i]);
    }
}
function drawElement(context, element) {
    context.fillStyle = element.color;
    context.fillRect(element.left, element.top, element.width, element.height);
}
function getHitElement(elements, x, y) {
    var hitElement;
    for (var i = 0; i < elements.length; i++) {
        if (y > elements[i].top && y < elements[i].top + elements[i].height && 
            x > elements[i].left && x < elements[i].left + elements[i].width) {
            hitElement = elements[i];
        }
    }
    return hitElement;
}

Why is it that I cannot hook up an event handler to each individual element?

为什么我无法将事件处理程序连接到每个单独的元素?

回答by jfriend00

Your specific error:

您的具体错误:

'Uncaught TypeError: elements[i].addEventListener is not a function'

is because elements[i].addEventListeneris undefinedand thus is not a function. The reason it is undefinedis because your elementsarray contains regular Javascript objects. Those objects do not have a .addEventListener()method. That is a method on DOM objects that are an EventTarget, not regular Javascript objects (unless you make your own method called addEventListenerand add it to your Javascript objects).

是因为elements[i].addEventListenerundefined,因此不是函数。原因undefined是因为您的elements数组包含常规 Javascript 对象。这些对象没有.addEventListener()方法。这是 DOM 对象上的一种方法EventTarget,它不是常规的 Javascript 对象(除非您调用自己的方法addEventListener并将其添加到您的 Javascript 对象中)。

Since I don't see a corresponding array of DOM elements in your code, it appears like you're trying to attach eventListeners to rectangles you draw on your Canvas which is not something you can do in that way. T'he things you've drawn on a Canvas object are basically like a bitmap. It doesn't retain a knowledge of objects you drew on it other than the resulting pixels. You draw on it and the result is pixels on the canvas, not a persistent set of objects such as DOM objects. If you want to later do hit testing versus things you drew on the canvas, then you'd have to put an eventListener on the canvas object itself to get the input event, keep track yourself of what object you drew where on the canvas and then when the event triggers on your canvas listener, you can do your own hit testing versus that data of what you put where.

由于我在您的代码中没有看到相应的 DOM 元素数组,因此您似乎正在尝试将 eventListeners 附加到您在 Canvas 上绘制的矩形,这不是您可以通过这种方式执行的操作。你在 Canvas 对象上绘制的东西基本上就像一个位图。除了生成的像素之外,它不会保留您在其上绘制的对象的知识。你在它上面画画,结果是画布上的像素,而不是一组持久化的对象,比如 DOM 对象。如果您想稍后对在画布上绘制的内容进行命中测试,那么您必须在画布对象本身上放置一个 eventListener 以获取输入事件,跟踪自己在画布上绘制的对象,然后当事件在您的画布侦听器上触发时,

回答by Illyism

You're making an array of basic javascript objects. Which don't have the addEventListener method which are only used in EventTargetobjects.

您正在制作一组基本的 javascript 对象。没有仅在EventTarget对象中使用的 addEventListener 方法。

Look at this similar questionfor an idea on how to do what you want to do

看看这个类似的问题,了解如何做你想做的事

回答by PM 77-1

You are trying to attach EventListener()to objects that do not support events.

您正在尝试附加EventListener()到不支持事件的对象。

From the docs:

文档

The event target may be an Elementin a document, the Documentitself, a Window, or any other object that supports events (such as XMLHttpRequest).

事件目标可以是Element文档中的 、Document本身Window、 或任何其他支持事件的对象(例如 XMLHttpRequest)。

What you call elementsdoes not match any of the above criteria.

您所称的内容elements不符合上述任何条件。