JavaScript对象:'addEventListener不是函数'

时间:2015-06-19 19:56:21

标签: javascript html object canvas mapping

我创建了一个名为elements的JavaScript对象数组,并在其中循环,以便在画布上绘制每个对象,并将几个事件处理程序连接到它。但是,我收到一条错误说明

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

以下是代码:

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

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

3 个答案:

答案 0 :(得分:11)

您的具体错误:

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

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

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

答案 1 :(得分:1)

你正在制作一系列基本的javascript对象。其中没有仅在EventTarget个对象中使用的addEventListener方法。

请看这个类似question的关于如何做你想做的事的想法

答案 2 :(得分:0)

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

来自the docs

  

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

您呼叫elements的内容与上述任何条件都不符。